Add select-{larger,smaller}-syntax-node commands

This commit is contained in:
Max Brunsfeld
2017-11-30 15:17:14 -08:00
parent 273d708a48
commit 203c38ca45
4 changed files with 40 additions and 2 deletions

View File

@@ -161,6 +161,8 @@
'ctrl-alt-shift-right': 'editor:select-to-next-subword-boundary'
'ctrl-alt-backspace': 'editor:delete-to-beginning-of-subword'
'ctrl-alt-delete': 'editor:delete-to-end-of-subword'
'ctrl-alt-up': 'editor:select-larger-syntax-node'
'ctrl-alt-down': 'editor:select-smaller-syntax-node'
'atom-workspace atom-text-editor:not([mini])':
# Atom specific

View File

@@ -160,6 +160,8 @@ module.exports = ({commandRegistry, commandInstaller, config, notificationManage
'editor:select-to-previous-subword-boundary': -> @selectToPreviousSubwordBoundary()
'editor:select-to-first-character-of-line': -> @selectToFirstCharacterOfLine()
'editor:select-line': -> @selectLinesContainingCursors()
'editor:select-larger-syntax-node': -> @selectLargerSyntaxNode()
'editor:select-smaller-syntax-node': -> @selectSmallerSyntaxNode()
}),
false
)

View File

@@ -3053,13 +3053,33 @@ class TextEditor {
return this.expandSelectionsBackward(selection => selection.selectToBeginningOfPreviousParagraph())
}
// Extended: For each selection, select the syntax node that contains
// that selection.
selectLargerSyntaxNode () {
const languageMode = this.buffer.getLanguageMode()
if (!languageMode.getRangeForSyntaxNodeContainingRange) return
this.expandSelectionsForward(selection => {
const range = languageMode.getRangeForSyntaxNodeContainingRange(selection.getBufferRange())
if (range) selection.setBufferRange(range)
const currentRange = selection.getBufferRange()
const newRange = languageMode.getRangeForSyntaxNodeContainingRange(currentRange)
if (newRange) {
if (!selection._rangeStack) selection._rangeStack = []
selection._rangeStack.push(currentRange)
selection.setBufferRange(newRange)
}
})
}
// Extended: Undo the effect a preceding call to {::selectLargerSyntaxNode}.
selectSmallerSyntaxNode () {
this.expandSelectionsForward(selection => {
if (selection._rangeStack) {
const lastRange = selection._rangeStack[selection._rangeStack.length - 1]
if (lastRange && selection.getBufferRange().containsRange(lastRange)) {
selection._rangeStack.length--
selection.setBufferRange(lastRange)
}
}
})
}

View File

@@ -220,6 +220,20 @@ class TreeSitterLanguageMode {
}
}
/*
* Syntax Tree APIs
*/
getRangeForSyntaxNodeContainingRange (range) {
const startIndex = this.buffer.characterIndexForPosition(range.start)
const endIndex = this.buffer.characterIndexForPosition(range.end)
let node = this.document.rootNode.descendantForIndex(startIndex, endIndex - 1)
while (node && node.startIndex === startIndex && node.endIndex === endIndex) {
node = node.parent
}
if (node) return new Range(node.startPosition, node.endPosition)
}
/*
* Section - Backward compatibility shims
*/