mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-11 19:17:09 +03:00
Merge pull request #677 from savetheclocktower/tree-sitter-more-fixes
Tree-sitter running fixes (August edition)
This commit is contained in:
commit
69038a1c4c
@ -12,7 +12,7 @@ const MAX_ROWS_TO_SCAN_BACKWARD_TRAVERSAL = Object.freeze(Point(-MAX_ROWS_TO_SCA
|
|||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
class BracketMatcherView {
|
class BracketMatcherView {
|
||||||
constructor (editor, editorElement, matchManager) {
|
constructor(editor, editorElement, matchManager) {
|
||||||
this.destroy = this.destroy.bind(this)
|
this.destroy = this.destroy.bind(this)
|
||||||
this.updateMatch = this.updateMatch.bind(this)
|
this.updateMatch = this.updateMatch.bind(this)
|
||||||
this.editor = editor
|
this.editor = editor
|
||||||
@ -65,11 +65,11 @@ class BracketMatcherView {
|
|||||||
this.updateMatch()
|
this.updateMatch()
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy () {
|
destroy() {
|
||||||
this.subscriptions.dispose()
|
this.subscriptions.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMatch () {
|
updateMatch() {
|
||||||
if (this.pairHighlighted) {
|
if (this.pairHighlighted) {
|
||||||
this.editor.destroyMarker(this.startMarker.id)
|
this.editor.destroyMarker(this.startMarker.id)
|
||||||
this.editor.destroyMarker(this.endMarker.id)
|
this.editor.destroyMarker(this.endMarker.id)
|
||||||
@ -113,13 +113,13 @@ class BracketMatcherView {
|
|||||||
this.tagHighlighted = highlightTag
|
this.tagHighlighted = highlightTag
|
||||||
}
|
}
|
||||||
|
|
||||||
selectMatchingBrackets () {
|
selectMatchingBrackets() {
|
||||||
if (!this.bracket1Range && !this.bracket2Range) return
|
if (!this.bracket1Range && !this.bracket2Range) return
|
||||||
this.editor.setSelectedBufferRanges([this.bracket1Range, this.bracket2Range])
|
this.editor.setSelectedBufferRanges([this.bracket1Range, this.bracket2Range])
|
||||||
this.matchManager.changeBracketsMode = true
|
this.matchManager.changeBracketsMode = true
|
||||||
}
|
}
|
||||||
|
|
||||||
removeMatchingBrackets () {
|
removeMatchingBrackets() {
|
||||||
if (this.editor.hasMultipleCursors()) {
|
if (this.editor.hasMultipleCursors()) {
|
||||||
this.editor.backspace()
|
this.editor.backspace()
|
||||||
return
|
return
|
||||||
@ -159,7 +159,7 @@ class BracketMatcherView {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingEndBracket (startBracketPosition, startBracket, endBracket) {
|
findMatchingEndBracket(startBracketPosition, startBracket, endBracket) {
|
||||||
if (startBracket === endBracket) return
|
if (startBracket === endBracket) return
|
||||||
|
|
||||||
if (this.hasSyntaxTree()) {
|
if (this.hasSyntaxTree()) {
|
||||||
@ -171,7 +171,7 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingStartBracket (endBracketPosition, startBracket, endBracket) {
|
findMatchingStartBracket(endBracketPosition, startBracket, endBracket) {
|
||||||
if (startBracket === endBracket) return
|
if (startBracket === endBracket) return
|
||||||
|
|
||||||
if (this.hasSyntaxTree()) {
|
if (this.hasSyntaxTree()) {
|
||||||
@ -183,7 +183,7 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingEndBracketWithSyntaxTree (bracketPosition, startBracket, endBracket) {
|
findMatchingEndBracketWithSyntaxTree(bracketPosition, startBracket, endBracket) {
|
||||||
let result
|
let result
|
||||||
const bracketEndPosition = bracketPosition.traverse([0, startBracket.length])
|
const bracketEndPosition = bracketPosition.traverse([0, startBracket.length])
|
||||||
this.editor.buffer.getLanguageMode().getSyntaxNodeContainingRange(
|
this.editor.buffer.getLanguageMode().getSyntaxNodeContainingRange(
|
||||||
@ -202,7 +202,7 @@ class BracketMatcherView {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingStartBracketWithSyntaxTree (bracketPosition, startBracket, endBracket) {
|
findMatchingStartBracketWithSyntaxTree(bracketPosition, startBracket, endBracket) {
|
||||||
let result
|
let result
|
||||||
const bracketEndPosition = bracketPosition.traverse([0, startBracket.length])
|
const bracketEndPosition = bracketPosition.traverse([0, startBracket.length])
|
||||||
this.editor.buffer.getLanguageMode().getSyntaxNodeContainingRange(
|
this.editor.buffer.getLanguageMode().getSyntaxNodeContainingRange(
|
||||||
@ -221,7 +221,7 @@ class BracketMatcherView {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingTagNameRangesWithSyntaxTree () {
|
findMatchingTagNameRangesWithSyntaxTree() {
|
||||||
const position = this.editor.getCursorBufferPosition()
|
const position = this.editor.getCursorBufferPosition()
|
||||||
const {startTag, endTag} = this.findContainingTagsWithSyntaxTree(position)
|
const {startTag, endTag} = this.findContainingTagsWithSyntaxTree(position)
|
||||||
if (startTag && (startTag.range.containsPoint(position) || endTag.range.containsPoint(position))) {
|
if (startTag && (startTag.range.containsPoint(position) || endTag.range.containsPoint(position))) {
|
||||||
@ -244,7 +244,7 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingTagsWithSyntaxTree () {
|
findMatchingTagsWithSyntaxTree() {
|
||||||
const position = this.editor.getCursorBufferPosition()
|
const position = this.editor.getCursorBufferPosition()
|
||||||
const {startTag, endTag} = this.findContainingTagsWithSyntaxTree(position)
|
const {startTag, endTag} = this.findContainingTagsWithSyntaxTree(position)
|
||||||
if (startTag) {
|
if (startTag) {
|
||||||
@ -254,7 +254,7 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findContainingTagsWithSyntaxTree (position) {
|
findContainingTagsWithSyntaxTree(position) {
|
||||||
let startTag, endTag
|
let startTag, endTag
|
||||||
if (position.column === this.editor.buffer.lineLengthForRow(position.row)) position.column--;
|
if (position.column === this.editor.buffer.lineLengthForRow(position.row)) position.column--;
|
||||||
this.editor.buffer.getLanguageMode().getSyntaxNodeAtPosition(position, node => {
|
this.editor.buffer.getLanguageMode().getSyntaxNodeAtPosition(position, node => {
|
||||||
@ -275,14 +275,14 @@ class BracketMatcherView {
|
|||||||
startTag = firstChild
|
startTag = firstChild
|
||||||
endTag = lastChild
|
endTag = lastChild
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return {startTag, endTag}
|
return {startTag, endTag}
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingEndBracketWithRegexSearch (startBracketPosition, startBracket, endBracket) {
|
findMatchingEndBracketWithRegexSearch(startBracketPosition, startBracket, endBracket) {
|
||||||
const scanRange = new Range(
|
const scanRange = new Range(
|
||||||
startBracketPosition.traverse(ONE_CHAR_FORWARD_TRAVERSAL),
|
startBracketPosition.traverse(ONE_CHAR_FORWARD_TRAVERSAL),
|
||||||
startBracketPosition.traverse(MAX_ROWS_TO_SCAN_FORWARD_TRAVERSAL)
|
startBracketPosition.traverse(MAX_ROWS_TO_SCAN_FORWARD_TRAVERSAL)
|
||||||
@ -308,7 +308,7 @@ class BracketMatcherView {
|
|||||||
return endBracketPosition
|
return endBracketPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
findMatchingStartBracketWithRegexSearch (endBracketPosition, startBracket, endBracket) {
|
findMatchingStartBracketWithRegexSearch(endBracketPosition, startBracket, endBracket) {
|
||||||
const scanRange = new Range(
|
const scanRange = new Range(
|
||||||
endBracketPosition.traverse(MAX_ROWS_TO_SCAN_BACKWARD_TRAVERSAL),
|
endBracketPosition.traverse(MAX_ROWS_TO_SCAN_BACKWARD_TRAVERSAL),
|
||||||
endBracketPosition
|
endBracketPosition
|
||||||
@ -334,7 +334,7 @@ class BracketMatcherView {
|
|||||||
return startBracketPosition
|
return startBracketPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
findPrecedingStartBracket (cursorPosition) {
|
findPrecedingStartBracket(cursorPosition) {
|
||||||
if (this.hasSyntaxTree()) {
|
if (this.hasSyntaxTree()) {
|
||||||
return this.findPrecedingStartBracketWithSyntaxTree(cursorPosition)
|
return this.findPrecedingStartBracketWithSyntaxTree(cursorPosition)
|
||||||
} else {
|
} else {
|
||||||
@ -342,7 +342,7 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findPrecedingStartBracketWithSyntaxTree (cursorPosition) {
|
findPrecedingStartBracketWithSyntaxTree(cursorPosition) {
|
||||||
let result
|
let result
|
||||||
this.editor.buffer.getLanguageMode().getSyntaxNodeAtPosition(cursorPosition, node => {
|
this.editor.buffer.getLanguageMode().getSyntaxNodeAtPosition(cursorPosition, node => {
|
||||||
for (const child of node.children) {
|
for (const child of node.children) {
|
||||||
@ -359,7 +359,7 @@ class BracketMatcherView {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
findPrecedingStartBracketWithRegexSearch (cursorPosition) {
|
findPrecedingStartBracketWithRegexSearch(cursorPosition) {
|
||||||
const scanRange = new Range(Point.ZERO, cursorPosition)
|
const scanRange = new Range(Point.ZERO, cursorPosition)
|
||||||
const startBracket = _.escapeRegExp(_.keys(this.matchManager.pairedCharacters).join(''))
|
const startBracket = _.escapeRegExp(_.keys(this.matchManager.pairedCharacters).join(''))
|
||||||
const endBracket = _.escapeRegExp(_.keys(this.matchManager.pairedCharactersInverse).join(''))
|
const endBracket = _.escapeRegExp(_.keys(this.matchManager.pairedCharactersInverse).join(''))
|
||||||
@ -384,7 +384,7 @@ class BracketMatcherView {
|
|||||||
return startPosition
|
return startPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
createMarker (bufferRange) {
|
createMarker(bufferRange) {
|
||||||
const marker = this.editor.markBufferRange(bufferRange)
|
const marker = this.editor.markBufferRange(bufferRange)
|
||||||
this.editor.decorateMarker(marker, {type: 'highlight', class: 'bracket-matcher', deprecatedRegionClass: 'bracket-matcher'})
|
this.editor.decorateMarker(marker, {type: 'highlight', class: 'bracket-matcher', deprecatedRegionClass: 'bracket-matcher'})
|
||||||
if (atom.config.get('bracket-matcher.highlightMatchingLineNumber', {scope: this.editor.getRootScopeDescriptor()}) && this.gutter) {
|
if (atom.config.get('bracket-matcher.highlightMatchingLineNumber', {scope: this.editor.getRootScopeDescriptor()}) && this.gutter) {
|
||||||
@ -393,7 +393,7 @@ class BracketMatcherView {
|
|||||||
return marker
|
return marker
|
||||||
}
|
}
|
||||||
|
|
||||||
findCurrentPair () {
|
findCurrentPair() {
|
||||||
const currentPosition = this.editor.getCursorBufferPosition()
|
const currentPosition = this.editor.getCursorBufferPosition()
|
||||||
const previousPosition = currentPosition.traverse(ONE_CHAR_BACKWARD_TRAVERSAL)
|
const previousPosition = currentPosition.traverse(ONE_CHAR_BACKWARD_TRAVERSAL)
|
||||||
const nextPosition = currentPosition.traverse(ONE_CHAR_FORWARD_TRAVERSAL)
|
const nextPosition = currentPosition.traverse(ONE_CHAR_FORWARD_TRAVERSAL)
|
||||||
@ -422,7 +422,7 @@ class BracketMatcherView {
|
|||||||
return {position, matchPosition, bracket: currentBracket}
|
return {position, matchPosition, bracket: currentBracket}
|
||||||
}
|
}
|
||||||
|
|
||||||
goToMatchingBracket () {
|
goToMatchingBracket() {
|
||||||
if (!this.pairHighlighted) return this.gotoPrecedingStartBracket()
|
if (!this.pairHighlighted) return this.gotoPrecedingStartBracket()
|
||||||
const position = this.editor.getCursorBufferPosition()
|
const position = this.editor.getCursorBufferPosition()
|
||||||
|
|
||||||
@ -468,7 +468,7 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gotoPrecedingStartBracket () {
|
gotoPrecedingStartBracket() {
|
||||||
if (this.pairHighlighted) return
|
if (this.pairHighlighted) return
|
||||||
|
|
||||||
const matchPosition = this.findPrecedingStartBracket(this.editor.getCursorBufferPosition())
|
const matchPosition = this.findPrecedingStartBracket(this.editor.getCursorBufferPosition())
|
||||||
@ -522,7 +522,7 @@ class BracketMatcherView {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
selectInsideBrackets () {
|
selectInsideBrackets() {
|
||||||
let endPosition, endRange, startPosition, startRange
|
let endPosition, endRange, startPosition, startRange
|
||||||
if (this.pairHighlighted) {
|
if (this.pairHighlighted) {
|
||||||
startRange = this.startMarker.getBufferRange()
|
startRange = this.startMarker.getBufferRange()
|
||||||
@ -550,7 +550,7 @@ class BracketMatcherView {
|
|||||||
|
|
||||||
// Insert at the current cursor position a closing tag if there exists an
|
// Insert at the current cursor position a closing tag if there exists an
|
||||||
// open tag that is not closed afterwards.
|
// open tag that is not closed afterwards.
|
||||||
closeTag () {
|
closeTag() {
|
||||||
const cursorPosition = this.editor.getCursorBufferPosition()
|
const cursorPosition = this.editor.getCursorBufferPosition()
|
||||||
const preFragment = this.editor.getTextInBufferRange([Point.ZERO, cursorPosition])
|
const preFragment = this.editor.getTextInBufferRange([Point.ZERO, cursorPosition])
|
||||||
const postFragment = this.editor.getTextInBufferRange([cursorPosition, Point.INFINITY])
|
const postFragment = this.editor.getTextInBufferRange([cursorPosition, Point.INFINITY])
|
||||||
@ -561,15 +561,15 @@ class BracketMatcherView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isCursorOnCommentOrString () {
|
isCursorOnCommentOrString() {
|
||||||
return this.isScopeCommentedOrString(this.editor.getLastCursor().getScopeDescriptor().getScopesArray())
|
return this.isScopeCommentedOrString(this.editor.getLastCursor().getScopeDescriptor().getScopesArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
isRangeCommentedOrString (range) {
|
isRangeCommentedOrString(range) {
|
||||||
return this.isScopeCommentedOrString(this.editor.scopeDescriptorForBufferPosition(range.start).getScopesArray())
|
return this.isScopeCommentedOrString(this.editor.scopeDescriptorForBufferPosition(range.start).getScopesArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
isScopeCommentedOrString (scopesArray) {
|
isScopeCommentedOrString(scopesArray) {
|
||||||
for (let scope of scopesArray.reverse()) {
|
for (let scope of scopesArray.reverse()) {
|
||||||
scope = scope.split('.')
|
scope = scope.split('.')
|
||||||
if (scope.includes('embedded') && scope.includes('source')) return false
|
if (scope.includes('embedded') && scope.includes('source')) return false
|
||||||
@ -579,7 +579,7 @@ class BracketMatcherView {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
hasSyntaxTree () {
|
hasSyntaxTree() {
|
||||||
return this.editor.buffer.getLanguageMode().getSyntaxNodeAtPosition
|
return this.editor.buffer.getLanguageMode().getSyntaxNodeAtPosition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,16 @@
|
|||||||
(primitive_type) @storage.type.builtin.c
|
(primitive_type) @storage.type.builtin.c
|
||||||
(type_identifier) @storage.type.other.c
|
(type_identifier) @storage.type.other.c
|
||||||
|
|
||||||
|
; These types are all reserved words; if we see an identifier with this name,
|
||||||
|
; it must be a type.
|
||||||
|
((identifier) @storage.type.builtin.c
|
||||||
|
(#match? @storage.type.builtin.c "^(char|int|float|double|long)$"))
|
||||||
|
|
||||||
|
; Assume any identifier that ends in `_t` is a type. This convention is not
|
||||||
|
; always followed, but it's a very strong indicator when it's present.
|
||||||
|
((identifier) @storage.type.other.c
|
||||||
|
(#match? @storage.type.other.c "_t$"))
|
||||||
|
|
||||||
[
|
[
|
||||||
"enum"
|
"enum"
|
||||||
"long"
|
"long"
|
||||||
@ -70,6 +80,10 @@
|
|||||||
((primitive_type) @support.type.stdint.c
|
((primitive_type) @support.type.stdint.c
|
||||||
(#match? @support.type.stdint.c "^(int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t)$"))
|
(#match? @support.type.stdint.c "^(int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t)$"))
|
||||||
|
|
||||||
|
(enum_specifier
|
||||||
|
name: (type_identifier) @variable.other.declaration.type.c)
|
||||||
|
(type_definition
|
||||||
|
declarator: (_) @variable.other.declaration.type.c)
|
||||||
|
|
||||||
; CAVEAT: tree-sitter-c doesn't identify placeholders like `%c` in strings.
|
; CAVEAT: tree-sitter-c doesn't identify placeholders like `%c` in strings.
|
||||||
; Candidate for an injection grammar.
|
; Candidate for an injection grammar.
|
||||||
@ -111,19 +125,19 @@
|
|||||||
declarator: (identifier) @variable.declaration.c)
|
declarator: (identifier) @variable.declaration.c)
|
||||||
|
|
||||||
(field_declaration
|
(field_declaration
|
||||||
(field_identifier) @variable.declaration.c)
|
(field_identifier) @entity.other.attribute-name.c)
|
||||||
|
|
||||||
(field_declaration
|
(field_declaration
|
||||||
(pointer_declarator
|
(pointer_declarator
|
||||||
(field_identifier) @variable.declaration.c))
|
(field_identifier) @entity.other.attribute-name.c))
|
||||||
|
|
||||||
(field_declaration
|
(field_declaration
|
||||||
(array_declarator
|
(array_declarator
|
||||||
(field_identifier) @variable.declaration.c))
|
(field_identifier) @entity.other.attribute-name.c))
|
||||||
|
|
||||||
(init_declarator
|
(init_declarator
|
||||||
(pointer_declarator
|
(pointer_declarator
|
||||||
(identifier) @variable.declaration.c))
|
(identifier) @entity.other.attribute-name.c))
|
||||||
|
|
||||||
(assignment_expression
|
(assignment_expression
|
||||||
left: (identifier) @variable.other.assignment.c)
|
left: (identifier) @variable.other.assignment.c)
|
||||||
@ -158,7 +172,7 @@
|
|||||||
; The "size" in `finfo->size`.
|
; The "size" in `finfo->size`.
|
||||||
(field_expression
|
(field_expression
|
||||||
"->"
|
"->"
|
||||||
field: (field_identifier) @variable.other.member.c)
|
field: (field_identifier) @support.other.property.c)
|
||||||
|
|
||||||
|
|
||||||
; FUNCTIONS
|
; FUNCTIONS
|
||||||
|
@ -1 +0,0 @@
|
|||||||
;
|
|
@ -1,2 +1,3 @@
|
|||||||
|
|
||||||
((function_declarator (identifier) @name))
|
(function_declarator
|
||||||
|
(identifier) @name) @definition.function
|
||||||
|
@ -58,6 +58,17 @@
|
|||||||
(type_identifier) @storage.type.other.cpp
|
(type_identifier) @storage.type.other.cpp
|
||||||
; (struct_specifier) @storage.type.cpp
|
; (struct_specifier) @storage.type.cpp
|
||||||
|
|
||||||
|
; These types are all reserved words; if we see an identifier with this name,
|
||||||
|
; it must be a type.
|
||||||
|
((identifier) @storage.type.builtin.cpp
|
||||||
|
(#match? @storage.type.builtin.cpp "^(char|int|float|double|long)$"))
|
||||||
|
|
||||||
|
; Assume any identifier that ends in `_t` is a type. This convention is not
|
||||||
|
; always followed, but it's a very strong indicator when it's present.
|
||||||
|
((identifier) @storage.type.other.cpp
|
||||||
|
(#match? @storage.type.other.cpp "_t$"))
|
||||||
|
|
||||||
|
|
||||||
[
|
[
|
||||||
"enum"
|
"enum"
|
||||||
"long"
|
"long"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
;
|
|
@ -1,2 +1,16 @@
|
|||||||
|
|
||||||
((function_declarator (identifier) @name))
|
(function_declarator
|
||||||
|
(identifier) @name) @definition.function
|
||||||
|
|
||||||
|
(function_declarator
|
||||||
|
declarator: (qualified_identifier) @name) @definition.function
|
||||||
|
|
||||||
|
(class_specifier
|
||||||
|
name: (type_identifier) @name) @definition.class
|
||||||
|
|
||||||
|
(class_specifier
|
||||||
|
body: (field_declaration_list
|
||||||
|
(function_definition
|
||||||
|
declarator: (function_declarator
|
||||||
|
declarator: (field_identifier) @name)) @definition.method)
|
||||||
|
(#set! symbol.contextNode "parent.parent.parent.parent.firstNamedChild"))
|
||||||
|
@ -156,7 +156,7 @@
|
|||||||
; ------------------------
|
; ------------------------
|
||||||
|
|
||||||
((plain_value) @support.constant.property-value.css
|
((plain_value) @support.constant.property-value.css
|
||||||
(#match? @support.constant.property-value.css "^(above|absolute|active|add|additive|after-edge|alias|all|all-petite-caps|all-scroll|all-small-caps|alpha|alphabetic|alternate|alternate-reverse|always|antialiased|auto|auto-pos|available|avoid|avoid-column|avoid-page|avoid-region|backwards|balance|baseline|before-edge|below|bevel|bidi-override|blink|block|block-axis|block-start|block-end|bold|bolder|border|border-box|both|bottom|bottom-outside|break-all|break-word|bullets|butt|capitalize|caption|cell|center|central|char|circle|clip|clone|close-quote|closest-corner|closest-side|col-resize|collapse|color|color-burn|color-dodge|column|column-reverse|common-ligatures|compact|condensed|contain|content|content-box|contents|context-menu|contextual|copy|cover|crisp-edges|crispEdges|crosshair|cyclic|dark|darken|dashed|decimal|default|dense|diagonal-fractions|difference|digits|disabled|disc|discretionary-ligatures|distribute|distribute-all-lines|distribute-letter|distribute-space|dot|dotted|double|double-circle|downleft|downright|e-resize|each-line|ease|ease-in|ease-in-out|ease-out|economy|ellipse|ellipsis|embed|end|evenodd|ew-resize|exact|exclude|exclusion|expanded|extends|extra-condensed|extra-expanded|fallback|farthest-corner|farthest-side|fill|fill-available|fill-box|filled|fit-content|fixed|flat|flex|flex-end|flex-start|flip|flow-root|forwards|freeze|from-image|full-width|geometricPrecision|georgian|grab|grabbing|grayscale|grid|groove|hand|hanging|hard-light|help|hidden|hide|historical-forms|historical-ligatures|horizontal|horizontal-tb|hue|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|infinite|inherit|initial|inline|inline-axis|inline-block|inline-end|inline-flex|inline-grid|inline-list-item|inline-start|inline-table|inset|inside|inter-character|inter-ideograph|inter-word|intersect|invert|isolate|isolate-override|italic|jis04|jis78|jis83|jis90|justify|justify-all|kannada|keep-all|landscape|large|larger|left|light|lighten|lighter|line|line-edge|line-through|linear|linearRGB|lining-nums|list-item|local|loose|lowercase|lr|lr-tb|ltr|luminance|luminosity|main-size|mandatory|manipulation|manual|margin-box|match-parent|match-source|mathematical|max-content|medium|menu|message-box|middle|min-content|miter|mixed|move|multiply|n-resize|narrower|ne-resize|nearest-neighbor|nesw-resize|newspaper|no-change|no-clip|no-close-quote|no-common-ligatures|no-contextual|no-discretionary-ligatures|no-drop|no-historical-ligatures|no-open-quote|no-repeat|none|nonzero|normal|not-allowed|nowrap|ns-resize|numbers|numeric|nw-resize|nwse-resize|oblique|oldstyle-nums|open|open-quote|optimizeLegibility|optimizeQuality|optimizeSpeed|optional|ordinal|outset|outside|over|overlay|overline|padding|padding-box|page|painted|pan-down|pan-left|pan-right|pan-up|pan-x|pan-y|paused|petite-caps|pixelated|plaintext|pointer|portrait|pre|pre-line|pre-wrap|preserve-3d|progress|progressive|proportional-nums|proportional-width|proximity|radial|recto|region|relative|remove|repeat|repeat-[xy]|reset-size|reverse|revert|ridge|right|rl|rl-tb|round|row|row-resize|row-reverse|row-severse|rtl|ruby|ruby-base|ruby-base-container|ruby-text|ruby-text-container|run-in|running|s-resize|saturation|scale-down|screen|scroll|scroll-position|se-resize|semi-condensed|semi-expanded|separate|sesame|show|sideways|sideways-left|sideways-lr|sideways-right|sideways-rl|simplified|slashed-zero|slice|small|small-caps|small-caption|smaller|smooth|soft-light|solid|space|space-around|space-between|space-evenly|spell-out|square|sRGB|stacked-fractions|start|static|status-bar|swap|step-end|step-start|sticky|stretch|strict|stroke|stroke-box|style|sub|subgrid|subpixel-antialiased|subtract|super|sw-resize|symbolic|table|table-caption|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row|table-row-group|tabular-nums|tb|tb-rl|text|text-after-edge|text-before-edge|text-bottom|text-top|thick|thin|titling-caps|top|top-outside|touch|traditional|transparent|triangle|ultra-condensed|ultra-expanded|under|underline|unicase|unset|upleft|uppercase|upright|use-glyph-orientation|use-script|verso|vertical|vertical-ideographic|vertical-lr|vertical-rl|vertical-text|view-box|visible|visibleFill|visiblePainted|visibleStroke|w-resize|wait|wavy|weight|whitespace|wider|words|wrap|wrap-reverse|x|x-large|x-small|xx-large|xx-small|y|zero|zoom-in|zoom-out)$"))
|
(#match? @support.constant.property-value.css "^(above|absolute|active|add|additive|after-edge|alias|all|all-petite-caps|all-scroll|all-small-caps|alpha|alphabetic|alternate|alternate-reverse|always|antialiased|auto|auto-pos|available|avoid|avoid-column|avoid-page|avoid-region|backwards|balance|baseline|before-edge|below|bevel|bidi-override|blink|block|block-axis|block-start|block-end|bold|bolder|border|border-box|both|bottom|bottom-outside|break-all|break-word|bullets|butt|capitalize|caption|cell|center|central|char|circle|clip|clone|close-quote|closest-corner|closest-side|col-resize|collapse|color|color-burn|color-dodge|column|column-reverse|common-ligatures|compact|condensed|contain|content|content-box|contents|context-menu|contextual|copy|cover|crisp-edges|crispEdges|crosshair|cyclic|dark|darken|dashed|decimal|default|dense|diagonal-fractions|difference|digits|disabled|disc|discretionary-ligatures|distribute|distribute-all-lines|distribute-letter|distribute-space|dot|dotted|double|double-circle|downleft|downright|e-resize|each-line|ease|ease-in|ease-in-out|ease-out|economy|ellipse|ellipsis|embed|end|evenodd|ew-resize|exact|exclude|exclusion|expanded|extends|extra-condensed|extra-expanded|fallback|farthest-corner|farthest-side|fill|fill-available|fill-box|filled|fit-content|fixed|flat|flex|flex-end|flex-start|flip|flow-root|forwards|freeze|from-image|full-width|geometricPrecision|georgian|grab|grabbing|grayscale|grid|groove|hand|hanging|hard-light|help|hidden|hide|historical-forms|historical-ligatures|horizontal|horizontal-tb|hue|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|infinite|inherit|initial|inline|inline-axis|inline-block|inline-end|inline-flex|inline-grid|inline-list-item|inline-size|inline-start|inline-table|inset|inside|inter-character|inter-ideograph|inter-word|intersect|invert|isolate|isolate-override|italic|jis04|jis78|jis83|jis90|justify|justify-all|kannada|keep-all|landscape|large|larger|layout|left|light|lighten|lighter|line|line-edge|line-through|linear|linearRGB|lining-nums|list-item|local|loose|lowercase|lr|lr-tb|ltr|luminance|luminosity|main-size|mandatory|manipulation|manual|margin-box|match-parent|match-source|mathematical|max-content|medium|menu|message-box|middle|min-content|miter|mixed|move|multiply|n-resize|narrower|ne-resize|nearest-neighbor|nesw-resize|newspaper|no-change|no-clip|no-close-quote|no-common-ligatures|no-contextual|no-discretionary-ligatures|no-drop|no-historical-ligatures|no-open-quote|no-repeat|none|nonzero|normal|not-allowed|nowrap|ns-resize|numbers|numeric|nw-resize|nwse-resize|oblique|oldstyle-nums|open|open-quote|optimizeLegibility|optimizeQuality|optimizeSpeed|optional|ordinal|outset|outside|over|overlay|overline|padding|padding-box|page|paint|painted|pan-down|pan-left|pan-right|pan-up|pan-x|pan-y|paused|petite-caps|pixelated|plaintext|pointer|portrait|pre|pre-line|pre-wrap|preserve-3d|progress|progressive|proportional-nums|proportional-width|proximity|radial|recto|region|relative|remove|repeat|repeat-[xy]|reset-size|reverse|revert|ridge|right|rl|rl-tb|round|row|row-resize|row-reverse|row-severse|rtl|ruby|ruby-base|ruby-base-container|ruby-text|ruby-text-container|run-in|running|s-resize|saturation|scale-down|screen|scroll|scroll-position|se-resize|semi-condensed|semi-expanded|separate|sesame|show|sideways|sideways-left|sideways-lr|sideways-right|sideways-rl|simplified|size|slashed-zero|slice|small|small-caps|small-caption|smaller|smooth|soft-light|solid|space|space-around|space-between|space-evenly|spell-out|square|sRGB|stacked-fractions|start|static|status-bar|swap|step-end|step-start|sticky|stretch|strict|stroke|stroke-box|style|sub|subgrid|subpixel-antialiased|subtract|super|sw-resize|symbolic|table|table-caption|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row|table-row-group|tabular-nums|tb|tb-rl|text|text-after-edge|text-before-edge|text-bottom|text-top|thick|thin|titling-caps|top|top-outside|touch|traditional|transparent|triangle|ultra-condensed|ultra-expanded|under|underline|unicase|unset|upleft|uppercase|upright|use-glyph-orientation|use-script|verso|vertical|vertical-ideographic|vertical-lr|vertical-rl|vertical-text|view-box|visible|visibleFill|visiblePainted|visibleStroke|w-resize|wait|wavy|weight|whitespace|wider|words|wrap|wrap-reverse|x|x-large|x-small|xx-large|xx-small|y|zero|zoom-in|zoom-out)$"))
|
||||||
|
|
||||||
; All property values that have special meaning in `font-family`.
|
; All property values that have special meaning in `font-family`.
|
||||||
; TODO: Restrict these to be meaningful only when the property name is font-related?
|
; TODO: Restrict these to be meaningful only when the property name is font-related?
|
||||||
|
@ -3,15 +3,23 @@
|
|||||||
(switch_body)
|
(switch_body)
|
||||||
(class_body)
|
(class_body)
|
||||||
(object)
|
(object)
|
||||||
(formal_parameters)
|
|
||||||
(template_string)
|
(template_string)
|
||||||
(named_imports)
|
(named_imports)
|
||||||
] @fold
|
] @fold
|
||||||
|
|
||||||
((arguments) @fold
|
; When we've got
|
||||||
|
;
|
||||||
|
; function foo(
|
||||||
|
; bar,
|
||||||
|
; baz,
|
||||||
|
; thud
|
||||||
|
; )
|
||||||
|
;
|
||||||
|
; we want to be able to fold up the group of function parameters while
|
||||||
|
; preserving the ability to collapse the function body.
|
||||||
|
([(arguments) (formal_parameters)] @fold
|
||||||
(#set! fold.adjustToEndOfPreviousRow true))
|
(#set! fold.adjustToEndOfPreviousRow true))
|
||||||
|
|
||||||
|
|
||||||
; When we've got
|
; When we've got
|
||||||
;
|
;
|
||||||
; if (foo) {
|
; if (foo) {
|
||||||
@ -32,7 +40,7 @@
|
|||||||
|
|
||||||
((comment) @fold
|
((comment) @fold
|
||||||
(#set! fold.endAt endPosition)
|
(#set! fold.endAt endPosition)
|
||||||
(#set! fold.adjustEndColumn 0))
|
(#set! fold.offsetEnd -2))
|
||||||
|
|
||||||
|
|
||||||
; When you have…
|
; When you have…
|
||||||
|
@ -543,10 +543,18 @@
|
|||||||
(#match? @punctuation.definition.comment.js "^\/\/")
|
(#match? @punctuation.definition.comment.js "^\/\/")
|
||||||
(#set! adjust.startAndEndAroundFirstMatchOf "^\/\/"))
|
(#set! adjust.startAndEndAroundFirstMatchOf "^\/\/"))
|
||||||
|
|
||||||
|
((comment) @comment.block.documentation.js
|
||||||
|
(#match? @comment.block.documentation.js "^/\\*\\*")
|
||||||
|
(#set! capture.final true)
|
||||||
|
(#set! highlight.invalidateOnChange true))
|
||||||
|
|
||||||
|
|
||||||
; Block comments. `/* */`
|
; Block comments. `/* */`
|
||||||
((comment) @comment.block.js
|
((comment) @comment.block.js
|
||||||
(#match? @comment.block.js "^/\\*")
|
(#match? @comment.block.js "^/\\*")
|
||||||
(#match? @comment.block.js "\\*/$"))
|
(#match? @comment.block.js "\\*/$")
|
||||||
|
(#set! highlight.invalidateOnChange true))
|
||||||
|
|
||||||
|
|
||||||
((comment) @punctuation.definition.comment.begin.js
|
((comment) @punctuation.definition.comment.begin.js
|
||||||
(#match? @punctuation.definition.comment.begin.js "^/\\*")
|
(#match? @punctuation.definition.comment.begin.js "^/\\*")
|
||||||
@ -888,29 +896,43 @@
|
|||||||
; The interiors of functions (useful for snippets and commands).
|
; The interiors of functions (useful for snippets and commands).
|
||||||
(method_definition
|
(method_definition
|
||||||
body: (statement_block) @meta.block.function.js
|
body: (statement_block) @meta.block.function.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition)
|
||||||
(#set! capture.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
(function_declaration
|
(function_declaration
|
||||||
body: (statement_block) @meta.block.function.js
|
body: (statement_block) @meta.block.function.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition)
|
||||||
(#set! capture.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
(generator_function_declaration
|
(generator_function_declaration
|
||||||
body: (statement_block) @meta.block.function.js
|
body: (statement_block) @meta.block.function.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition)
|
||||||
(#set! capture.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
(function
|
(function
|
||||||
body: (statement_block) @meta.block.function.js
|
body: (statement_block) @meta.block.function.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition)
|
||||||
(#set! capture.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
(generator_function
|
(generator_function
|
||||||
body: (statement_block) @meta.block.function.js
|
body: (statement_block) @meta.block.function.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition)
|
||||||
(#set! capture.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
; The interior of a class body (useful for snippets and commands).
|
; The interior of a class body (useful for snippets and commands).
|
||||||
(class_body) @meta.block.class.js
|
((class_body) @meta.block.class.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
|
||||||
; All other sorts of blocks.
|
; All other sorts of blocks.
|
||||||
(statement_block) @meta.block.js
|
((statement_block) @meta.block.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
|
||||||
; The inside of a parameter definition list.
|
; The inside of a parameter definition list.
|
||||||
((formal_parameters) @meta.parameters.js
|
((formal_parameters) @meta.parameters.js
|
||||||
@ -923,6 +945,20 @@
|
|||||||
(#set! adjust.endAt lastChild.startPosition))
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
|
||||||
|
|
||||||
|
([
|
||||||
|
(jsx_opening_element)
|
||||||
|
(jsx_closing_element)
|
||||||
|
] @meta.jsx.inside-tag.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition))
|
||||||
|
|
||||||
|
((jsx_self_closing_element) @meta.jsx.inside-tag.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
|
||||||
|
((jsx_element) @meta.block.jsx.js
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
|
||||||
; MISC
|
; MISC
|
||||||
; ====
|
; ====
|
||||||
|
|
||||||
|
@ -94,23 +94,25 @@
|
|||||||
; =============================
|
; =============================
|
||||||
|
|
||||||
; TODO: We might want to make this configurable behavior with the
|
; TODO: We might want to make this configurable behavior with the
|
||||||
; `Config` scope test.
|
; `config` scope test.
|
||||||
|
|
||||||
; Any of these at the end of a line indicate the next line should be indented…
|
; Any of these at the end of a line indicate the next line should be indented…
|
||||||
(["||" "&&" "?"] @indent
|
(["||" "&&" "?"] @indent
|
||||||
(#is? test.lastTextOnRow true))
|
(#is? test.lastTextOnRow true))
|
||||||
|
|
||||||
; …and the line after that should be dedented.
|
; …and the line after that should be dedented…
|
||||||
(binary_expression
|
(binary_expression
|
||||||
["||" "&&"]
|
["||" "&&"]
|
||||||
right: (_) @dedent.next
|
right: (_) @dedent.next
|
||||||
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
||||||
|
|
||||||
|
; …unless it's a ternary, in which case the dedent should wait until the
|
||||||
|
; alternative clause.
|
||||||
|
;
|
||||||
; let foo = this.longTernaryCondition() ?
|
; let foo = this.longTernaryCondition() ?
|
||||||
; consequenceWhichIsItselfRatherLong :
|
; consequenceWhichIsItselfRatherLong :
|
||||||
; alternativeThatIsNotBrief;
|
; alternativeThatIsNotBrief;
|
||||||
;
|
;
|
||||||
; …followed by a dedent.
|
|
||||||
(ternary_expression
|
(ternary_expression
|
||||||
alternative: (_) @dedent.next
|
alternative: (_) @dedent.next
|
||||||
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
||||||
@ -153,5 +155,8 @@
|
|||||||
; JSX
|
; JSX
|
||||||
; ===
|
; ===
|
||||||
|
|
||||||
(jsx_opening_element ">") @indent
|
|
||||||
(jsx_closing_element ">") @dedent
|
(jsx_opening_element ["<" ">"] @indent)
|
||||||
|
(jsx_opening_element [">"] @dedent)
|
||||||
|
|
||||||
|
(jsx_closing_element ">" @dedent)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
((document) @punctuation.definition.end.comment.js.jsdoc
|
((document) @punctuation.definition.end.comment.js.jsdoc
|
||||||
(#set! adjust.startAndEndAroundFirstMatchOf "(?:\\*)?\\*/$"))
|
(#set! adjust.startAndEndAroundFirstMatchOf "(?:\\*)?\\*/$"))
|
||||||
|
|
||||||
|
((inline_tag) @meta.inline-tag.js.jsdoc)
|
||||||
|
|
||||||
(tag_name) @storage.type.class.jsdoc
|
(tag_name) @storage.type.class.jsdoc
|
||||||
|
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
(comment)* @doc
|
(comment)* @doc
|
||||||
.
|
.
|
||||||
(method_definition
|
(method_definition
|
||||||
name: (property_identifier) @name) @definition.method
|
name: (property_identifier) @name
|
||||||
(#not-eq? @name "constructor")
|
(#set! symbol.contextNode "parent.parent.parent.firstNamedChild")
|
||||||
|
) @definition.method
|
||||||
|
; (#not-eq? @name "constructor")
|
||||||
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
(#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
||||||
(#select-adjacent! @doc @definition.method)
|
(#select-adjacent! @doc @definition.method)
|
||||||
)
|
)
|
||||||
@ -22,19 +24,6 @@
|
|||||||
name: (_) @name) @definition.class
|
name: (_) @name) @definition.class
|
||||||
)
|
)
|
||||||
|
|
||||||
; (
|
|
||||||
; (comment)* @doc
|
|
||||||
; .
|
|
||||||
; [
|
|
||||||
; (class
|
|
||||||
; name: (_) @name)
|
|
||||||
; (class_declaration
|
|
||||||
; name: (_) @name)
|
|
||||||
; ] @definition.class
|
|
||||||
; (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
|
|
||||||
; (#select-adjacent! @doc @definition.class)
|
|
||||||
; )
|
|
||||||
|
|
||||||
(
|
(
|
||||||
(comment)* @doc
|
(comment)* @doc
|
||||||
.
|
.
|
||||||
@ -87,19 +76,19 @@
|
|||||||
key: (property_identifier) @name
|
key: (property_identifier) @name
|
||||||
value: [(arrow_function) (function)]) @definition.function
|
value: [(arrow_function) (function)]) @definition.function
|
||||||
|
|
||||||
; (
|
(
|
||||||
; (call_expression
|
(call_expression
|
||||||
; function: (identifier) @name) @reference.call
|
function: (identifier) @name) @reference.call
|
||||||
; (#not-match? @name "^(require)$")
|
(#not-match? @name "^(require)$")
|
||||||
; )
|
)
|
||||||
;
|
|
||||||
; (call_expression
|
(call_expression
|
||||||
; function: (member_expression
|
function: (member_expression
|
||||||
; property: (property_identifier) @name)
|
property: (property_identifier) @name)
|
||||||
; arguments: (_) @reference.call)
|
arguments: (_)) @reference.call
|
||||||
;
|
|
||||||
; (new_expression
|
(new_expression
|
||||||
; constructor: (_) @name) @reference.class
|
constructor: (_) @name) @reference.class
|
||||||
|
|
||||||
(export_statement value: (assignment_expression left: (identifier) @name right: ([
|
(export_statement value: (assignment_expression left: (identifier) @name right: ([
|
||||||
(number)
|
(number)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
exports.activate = function() {
|
exports.activate = function () {
|
||||||
if (!atom.grammars.addInjectionPoint) return;
|
if (!atom.grammars.addInjectionPoint) return;
|
||||||
|
|
||||||
atom.grammars.addInjectionPoint('source.js', {
|
atom.grammars.addInjectionPoint('source.js', {
|
||||||
@ -70,41 +70,38 @@ exports.activate = function() {
|
|||||||
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
|
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
|
||||||
const HYPERLINK_PATTERN = /\bhttps?:/
|
const HYPERLINK_PATTERN = /\bhttps?:/
|
||||||
|
|
||||||
for (const scopeName of ['source.js', 'source.ts', 'source.ts.tsx']) {
|
atom.grammars.addInjectionPoint('source.js', {
|
||||||
atom.grammars.addInjectionPoint(scopeName, {
|
type: 'comment',
|
||||||
type: 'comment',
|
language(comment) {
|
||||||
language(comment) {
|
if (comment.text.startsWith('/**')) return 'jsdoc';
|
||||||
if (comment.text.startsWith('/**')) return 'jsdoc';
|
},
|
||||||
},
|
content(comment) {
|
||||||
content(comment) {
|
return comment;
|
||||||
return comment;
|
},
|
||||||
},
|
languageScope: null,
|
||||||
languageScope: null,
|
coverShallowerScopes: true
|
||||||
coverShallowerScopes: true
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Experiment: better to have one layer with lots of nodes, or lots of
|
// Experiment: better to have one layer with lots of nodes, or lots of
|
||||||
// layers each managing one node?
|
// layers each managing one node?
|
||||||
atom.grammars.addInjectionPoint(scopeName, {
|
atom.grammars.addInjectionPoint('source.js', {
|
||||||
type: 'comment',
|
type: 'comment',
|
||||||
|
language: (node) => {
|
||||||
|
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
|
||||||
|
},
|
||||||
|
content: (node) => node,
|
||||||
|
languageScope: null
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let type of ['template_string', 'string_fragment', 'comment']) {
|
||||||
|
atom.grammars.addInjectionPoint('source.js', {
|
||||||
|
type,
|
||||||
language: (node) => {
|
language: (node) => {
|
||||||
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
|
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
|
||||||
},
|
},
|
||||||
content: (node) => node,
|
content: (node) => node,
|
||||||
languageScope: null
|
languageScope: null
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let type of ['template_string', 'string_fragment', 'comment']) {
|
|
||||||
atom.grammars.addInjectionPoint(scopeName, {
|
|
||||||
type,
|
|
||||||
language: (node) => {
|
|
||||||
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
|
|
||||||
},
|
|
||||||
content: (node) => node,
|
|
||||||
languageScope: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,3 +11,13 @@
|
|||||||
'decreaseIndentPattern': '(?x)
|
'decreaseIndentPattern': '(?x)
|
||||||
^ \\s* (\\s* /[*] .* [*]/ \\s*)* [}\\])]
|
^ \\s* (\\s* /[*] .* [*]/ \\s*)* [}\\])]
|
||||||
'
|
'
|
||||||
|
|
||||||
|
'.source.js .meta.block.jsx.js':
|
||||||
|
'editor':
|
||||||
|
'commentStart': '{/*'
|
||||||
|
'commentEnd': '*/}'
|
||||||
|
|
||||||
|
'.source.js .meta.jsx.inside-tag.js':
|
||||||
|
'editor':
|
||||||
|
'commentStart': '{/*'
|
||||||
|
'commentEnd': '*/}'
|
||||||
|
@ -128,3 +128,18 @@
|
|||||||
'return':
|
'return':
|
||||||
'prefix': 'ret'
|
'prefix': 'ret'
|
||||||
'body': 'return $1;$0'
|
'body': 'return $1;$0'
|
||||||
|
|
||||||
|
'.source.js .meta.block.function.js':
|
||||||
|
'Function':
|
||||||
|
'prefix': 'fun'
|
||||||
|
'body': 'function ${1:functionName}($2) {\n\t$0\n}'
|
||||||
|
|
||||||
|
'.source.js .meta.block.class.js':
|
||||||
|
'Function':
|
||||||
|
'prefix': 'fun'
|
||||||
|
'body': '${1:functionName}($2) {\n\t$0\n}'
|
||||||
|
|
||||||
|
'.source.js .meta.object.js':
|
||||||
|
'Function':
|
||||||
|
'prefix': 'fun'
|
||||||
|
'body': '${1:functionName}($2) {\n\t$0\n},'
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
; Nested keys try to prepend the symbol name of their parent's key.
|
; Nested keys try to prepend the symbol name of their parent's key.
|
||||||
(pair key: (string (string_content) @name
|
(pair key: (string (string_content) @name
|
||||||
(#is-not? test.descendantOfType "array")
|
(#is-not? test.descendantOfType "array")
|
||||||
|
(#set! symbol.tag "property")
|
||||||
(#set! symbol.prependSymbolForNode parent.parent.parent.previousNamedSibling.firstNamedChild)
|
(#set! symbol.prependSymbolForNode parent.parent.parent.previousNamedSibling.firstNamedChild)
|
||||||
(#set! symbol.contextNode parent.parent.parent.previousNamedSibling.firstNamedChild)
|
(#set! symbol.contextNode parent.parent.parent.previousNamedSibling.firstNamedChild)
|
||||||
(#set! symbol.joiner ".")))
|
(#set! symbol.joiner ".")))
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
; * No support for lookbehind as of March 2023 (waiting on
|
; * No support for lookbehind as of March 2023 (waiting on
|
||||||
; https://github.com/tree-sitter/tree-sitter-regex/pull/15)
|
; https://github.com/tree-sitter/tree-sitter-regex/pull/15)
|
||||||
|
|
||||||
(pattern) @string.regexp
|
|
||||||
|
|
||||||
(non_capturing_group) @meta.group.non-capturing.regexp
|
(non_capturing_group) @meta.group.non-capturing.regexp
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
exports.activate = function() {
|
exports.activate = function () {
|
||||||
if (!atom.grammars.addInjectionPoint) return;
|
if (!atom.grammars.addInjectionPoint) return;
|
||||||
|
|
||||||
atom.grammars.addInjectionPoint('source.ruby', {
|
atom.grammars.addInjectionPoint('source.ruby', {
|
||||||
@ -19,6 +19,7 @@ exports.activate = function() {
|
|||||||
content(node) {
|
content(node) {
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
|
languageScope: null,
|
||||||
includeChildren: true,
|
includeChildren: true,
|
||||||
// coverShallowerScopes: false
|
// coverShallowerScopes: false
|
||||||
});
|
});
|
||||||
|
25
packages/language-shellscript/lib/main.js
Normal file
25
packages/language-shellscript/lib/main.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
exports.activate = () => {
|
||||||
|
|
||||||
|
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
|
||||||
|
const HYPERLINK_PATTERN = /\bhttps?:/
|
||||||
|
|
||||||
|
atom.grammars.addInjectionPoint('source.shell', {
|
||||||
|
type: 'comment',
|
||||||
|
language: (node) => {
|
||||||
|
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
|
||||||
|
},
|
||||||
|
content: (node) => node,
|
||||||
|
languageScope: null
|
||||||
|
});
|
||||||
|
|
||||||
|
atom.grammars.addInjectionPoint('source.shell', {
|
||||||
|
type: 'comment',
|
||||||
|
language(node) {
|
||||||
|
return HYPERLINK_PATTERN.test(node.text) ?
|
||||||
|
'hyperlink' : undefined;
|
||||||
|
},
|
||||||
|
content: (node) => node,
|
||||||
|
languageScope: null
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "language-shellscript",
|
"name": "language-shellscript",
|
||||||
"version": "0.28.2",
|
"version": "0.28.2",
|
||||||
|
"main": "lib/main",
|
||||||
"description": "ShellScript language support in Atom",
|
"description": "ShellScript language support in Atom",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tree-sitter"
|
"tree-sitter"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"atom": "*",
|
"atom": "*",
|
||||||
"node": "*"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"repository": "https://github.com/pulsar-edit/pulsar",
|
"repository": "https://github.com/pulsar-edit/pulsar",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -2,15 +2,23 @@
|
|||||||
(switch_body)
|
(switch_body)
|
||||||
(class_body)
|
(class_body)
|
||||||
(object)
|
(object)
|
||||||
(formal_parameters)
|
|
||||||
(template_string)
|
(template_string)
|
||||||
(named_imports)
|
(named_imports)
|
||||||
] @fold
|
] @fold
|
||||||
|
|
||||||
((arguments) @fold
|
; When we've got
|
||||||
|
;
|
||||||
|
; function foo(
|
||||||
|
; bar,
|
||||||
|
; baz,
|
||||||
|
; thud
|
||||||
|
; )
|
||||||
|
;
|
||||||
|
; we want to be able to fold up the group of function parameters while
|
||||||
|
; preserving the ability to collapse the function body.
|
||||||
|
([(arguments) (formal_parameters)] @fold
|
||||||
(#set! fold.adjustToEndOfPreviousRow true))
|
(#set! fold.adjustToEndOfPreviousRow true))
|
||||||
|
|
||||||
|
|
||||||
; When we've got
|
; When we've got
|
||||||
;
|
;
|
||||||
; if (foo) {
|
; if (foo) {
|
||||||
@ -31,4 +39,4 @@
|
|||||||
|
|
||||||
((comment) @fold
|
((comment) @fold
|
||||||
(#set! fold.endAt endPosition)
|
(#set! fold.endAt endPosition)
|
||||||
(#set! fold.adjustEndColumn 0))
|
(#set! fold.offsetEnd -2))
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
(import_specifier
|
(import_specifier
|
||||||
(identifier) @variable.other.assignment.import._LANG_)
|
(identifier) @variable.other.assignment.import._LANG_)
|
||||||
|
|
||||||
|
; The "foo" in `import * as foo from './bar'`
|
||||||
|
(namespace_import
|
||||||
|
(identifier) @variable.other.assignment.import.namespace._LANG_)
|
||||||
|
|
||||||
; The "Foo" in `export { Foo }`
|
; The "Foo" in `export { Foo }`
|
||||||
(export_specifier
|
(export_specifier
|
||||||
name: (identifier) @variable.other.assignment.export._LANG_)
|
name: (identifier) @variable.other.assignment.export._LANG_)
|
||||||
@ -37,8 +41,19 @@
|
|||||||
(#match? @punctuation.definition.comment._LANG_ "^//")
|
(#match? @punctuation.definition.comment._LANG_ "^//")
|
||||||
(#set! adjust.startAndEndAroundFirstMatchOf "^//"))
|
(#set! adjust.startAndEndAroundFirstMatchOf "^//"))
|
||||||
|
|
||||||
|
((comment) @comment.block.documentation._LANG_
|
||||||
|
(#match? @comment.block.documentation._LANG_ "^/\\*\\*")
|
||||||
|
(#set! capture.final true)
|
||||||
|
(#set! highlight.invalidateOnChange true))
|
||||||
|
|
||||||
|
; Block comments. `/* */`
|
||||||
((comment) @comment.block._LANG_
|
((comment) @comment.block._LANG_
|
||||||
(#match? @comment.block._LANG_ "^/\\*"))
|
(#match? @comment.block._LANG_ "^/\\*")
|
||||||
|
(#match? @comment.block._LANG_ "\\*/$")
|
||||||
|
(#set! highlight.invalidateOnChange true))
|
||||||
|
|
||||||
|
; ((comment) @comment.block._LANG_
|
||||||
|
; (#match? @comment.block._LANG_ "^/\\*"))
|
||||||
|
|
||||||
((comment) @punctuation.definition.comment.begin._LANG_
|
((comment) @punctuation.definition.comment.begin._LANG_
|
||||||
(#match? @punctuation.definition.comment.begin._LANG_ "^/\\*")
|
(#match? @punctuation.definition.comment.begin._LANG_ "^/\\*")
|
||||||
@ -65,7 +80,8 @@
|
|||||||
; =======
|
; =======
|
||||||
|
|
||||||
(class_declaration
|
(class_declaration
|
||||||
name: (type_identifier) @entity.name.type.class._LANG_)
|
name: (type_identifier) @entity.name.type.class._LANG_
|
||||||
|
(#set! capture.final true))
|
||||||
|
|
||||||
(extends_clause
|
(extends_clause
|
||||||
value: (_) @entity.other.inherited-class._LANG_)
|
value: (_) @entity.other.inherited-class._LANG_)
|
||||||
@ -90,12 +106,27 @@
|
|||||||
"set" @storage.setter._LANG_)
|
"set" @storage.setter._LANG_)
|
||||||
|
|
||||||
|
|
||||||
|
; NAMESPACES
|
||||||
|
; ==========
|
||||||
|
|
||||||
|
(internal_module
|
||||||
|
name: (identifier) @entity.name.type.namespace._LANG_)
|
||||||
|
|
||||||
|
|
||||||
|
; DECLARATIONS
|
||||||
|
; ============
|
||||||
|
|
||||||
|
(function_signature
|
||||||
|
name: (identifier) @entity.name.function.signature._LANG_)
|
||||||
|
|
||||||
|
|
||||||
; INTERFACES
|
; INTERFACES
|
||||||
; ==========
|
; ==========
|
||||||
|
|
||||||
(interface_declaration
|
(interface_declaration
|
||||||
name: (_) @entity.name.type.interface._LANG_)
|
name: (_) @entity.name.type.interface._LANG_)
|
||||||
|
|
||||||
|
|
||||||
; TYPES
|
; TYPES
|
||||||
; =====
|
; =====
|
||||||
|
|
||||||
@ -178,6 +209,8 @@
|
|||||||
(property_signature
|
(property_signature
|
||||||
(property_identifier) @entity.other.attribute-name._LANG_)
|
(property_identifier) @entity.other.attribute-name._LANG_)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; FUNCTIONS
|
; FUNCTIONS
|
||||||
; =========
|
; =========
|
||||||
|
|
||||||
@ -259,6 +292,10 @@
|
|||||||
(required_parameter
|
(required_parameter
|
||||||
pattern: (identifier) @variable.parameter._LANG_)
|
pattern: (identifier) @variable.parameter._LANG_)
|
||||||
|
|
||||||
|
(required_parameter
|
||||||
|
pattern: (rest_pattern
|
||||||
|
(identifier) @variable.parameter.rest._LANG_))
|
||||||
|
|
||||||
(required_parameter
|
(required_parameter
|
||||||
pattern: (object_pattern
|
pattern: (object_pattern
|
||||||
(shorthand_property_identifier_pattern) @variable.parameter.destructuring._LANG_)
|
(shorthand_property_identifier_pattern) @variable.parameter.destructuring._LANG_)
|
||||||
@ -269,6 +306,9 @@
|
|||||||
|
|
||||||
(optional_parameter "?" @keyword.operator.type.optional._LANG_)
|
(optional_parameter "?" @keyword.operator.type.optional._LANG_)
|
||||||
|
|
||||||
|
(type_predicate
|
||||||
|
name: (identifier) @variable.other.type._LANG_
|
||||||
|
"is" @keyword.operator.type.is._LANG_)
|
||||||
|
|
||||||
["var" "const" "let"] @storage.type._TYPE_._LANG_
|
["var" "const" "let"] @storage.type._TYPE_._LANG_
|
||||||
|
|
||||||
@ -306,7 +346,16 @@
|
|||||||
(pair_pattern
|
(pair_pattern
|
||||||
; TODO: This arguably isn't an object key.
|
; TODO: This arguably isn't an object key.
|
||||||
key: (_) @entity.other.attribute-name._LANG_
|
key: (_) @entity.other.attribute-name._LANG_
|
||||||
value: (identifier) @variable.other.assignment.destructuring._LANG_))
|
value: (identifier) @variable.other.assignment.destructuring._LANG_)
|
||||||
|
(#set! capture.final true))
|
||||||
|
|
||||||
|
; A complex object alias destructuring:
|
||||||
|
; The "bar" in `let { bar: { foo: troz } } = something`
|
||||||
|
(object_pattern
|
||||||
|
(pair_pattern
|
||||||
|
; TODO: This arguably isn't an object key.
|
||||||
|
key: (_) @entity.other.attribute-name._LANG_)
|
||||||
|
(#set! capture.final true))
|
||||||
|
|
||||||
; A variable object alias destructuring with default value:
|
; A variable object alias destructuring with default value:
|
||||||
; The "bar" and "foo" in `let { bar: foo = true } = something`
|
; The "bar" and "foo" in `let { bar: foo = true } = something`
|
||||||
|
@ -1,14 +1,124 @@
|
|||||||
; The closing brace of a switch statement's body should match the indentation of the line where the switch statement starts.
|
; STATEMENT BLOCKS
|
||||||
|
; ================
|
||||||
|
|
||||||
|
; More accurate indentation matching for all blocks delimited by braces.
|
||||||
|
(statement_block "}" @match
|
||||||
|
(#set! indent.matchIndentOf parent.firstChild.startPosition))
|
||||||
|
|
||||||
|
|
||||||
|
; SWITCH STATEMENTS
|
||||||
|
; =================
|
||||||
|
|
||||||
|
; The closing brace of a switch statement's body should match the indentation
|
||||||
|
; of the line where the switch statement starts.
|
||||||
(switch_statement
|
(switch_statement
|
||||||
body: (switch_body "}" @match
|
body: (switch_body "}" @match
|
||||||
(#is? test.last true))
|
(#is? test.last true))
|
||||||
(#set! indent.matchIndentOf parent.parent.startPosition))
|
(#set! indent.matchIndentOf parent.startPosition))
|
||||||
|
|
||||||
; 'case' and 'default' need to be indented one level more than their containing
|
; 'case' and 'default' need to be indented one level more than their containing
|
||||||
; `switch`.
|
; `switch`. TODO: Might need to make this configurable.
|
||||||
(["case" "default"] @match
|
(["case" "default"] @match
|
||||||
(#set! indent.matchIndentOf parent.parent.startPosition)
|
(#set! indent.matchIndentOf parent.parent.startPosition)
|
||||||
(#set! indent.offsetIndent 1))
|
(#set! indent.offsetIndent 1))
|
||||||
|
|
||||||
|
|
||||||
|
; ONE-LINE CONDITIONALS
|
||||||
|
; =====================
|
||||||
|
|
||||||
|
; An `if` statement without an opening brace should indent the next line…
|
||||||
|
(if_statement
|
||||||
|
condition: (parenthesized_expression ")" @indent
|
||||||
|
(#is? test.lastTextOnRow true)))
|
||||||
|
; (as should a braceless `else`…)
|
||||||
|
("else" @indent
|
||||||
|
(#is? test.lastTextOnRow true))
|
||||||
|
|
||||||
|
; …and keep that indent level if the user types a comment before the
|
||||||
|
; consequence…
|
||||||
|
(if_statement
|
||||||
|
consequence: (empty_statement) @match
|
||||||
|
(#is-not? test.startsOnSameRowAs parent.startPosition)
|
||||||
|
(#set! indent.matchIndentOf parent.startPosition)
|
||||||
|
(#set! indent.offsetIndent 1))
|
||||||
|
|
||||||
|
; …and keep that indent level after the user starts typing…
|
||||||
|
(if_statement
|
||||||
|
condition: (_) @indent
|
||||||
|
consequence: [
|
||||||
|
(expression_statement)
|
||||||
|
(return_statement)
|
||||||
|
(continue_statement)
|
||||||
|
(break_statement)
|
||||||
|
(throw_statement)
|
||||||
|
(debugger_statement)
|
||||||
|
] @match
|
||||||
|
; When an opening curly brace is unpaired, it might get interpreted as part
|
||||||
|
; of an `expression_statement`, for some reason.
|
||||||
|
(#not-match? @match "^\\s*{")
|
||||||
|
(#set! indent.matchIndentOf parent.startPosition)
|
||||||
|
(#set! indent.offsetIndent 1))
|
||||||
|
|
||||||
|
; …but dedent after exactly one statement.
|
||||||
|
(if_statement
|
||||||
|
condition: (_) @indent
|
||||||
|
consequence: [
|
||||||
|
(expression_statement)
|
||||||
|
(return_statement)
|
||||||
|
(continue_statement)
|
||||||
|
(break_statement)
|
||||||
|
(throw_statement)
|
||||||
|
(debugger_statement)
|
||||||
|
] @dedent.next
|
||||||
|
; When an opening curly brace is unpaired, it might get interpreted as part
|
||||||
|
; of an `expression_statement`, for some reason.
|
||||||
|
(#not-match? @dedent.next "^\\s*{"))
|
||||||
|
|
||||||
|
(else_clause
|
||||||
|
[
|
||||||
|
(expression_statement)
|
||||||
|
(return_statement)
|
||||||
|
(continue_statement)
|
||||||
|
(break_statement)
|
||||||
|
(throw_statement)
|
||||||
|
(debugger_statement)
|
||||||
|
] @dedent.next
|
||||||
|
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
||||||
|
|
||||||
|
; HANGING INDENT ON SPLIT LINES
|
||||||
|
; =============================
|
||||||
|
|
||||||
|
; TODO: We might want to make this configurable behavior with the
|
||||||
|
; `config` scope test.
|
||||||
|
|
||||||
|
; Any of these at the end of a line indicate the next line should be indented…
|
||||||
|
(["||" "&&" "?"] @indent
|
||||||
|
(#is? test.lastTextOnRow true))
|
||||||
|
|
||||||
|
; …and the line after that should be dedented.
|
||||||
|
(binary_expression
|
||||||
|
["||" "&&"]
|
||||||
|
right: (_) @dedent.next
|
||||||
|
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
||||||
|
|
||||||
|
; …unless it's a ternary, in which case the dedent should wait until the
|
||||||
|
; alternative clause.
|
||||||
|
;
|
||||||
|
; let foo = this.longTernaryCondition() ?
|
||||||
|
; consequenceWhichIsItselfRatherLong :
|
||||||
|
; alternativeThatIsNotBrief;
|
||||||
|
;
|
||||||
|
(ternary_expression
|
||||||
|
alternative: (_) @dedent.next
|
||||||
|
(#is-not? test.startsOnSameRowAs parent.startPosition))
|
||||||
|
|
||||||
|
|
||||||
|
; GENERAL
|
||||||
|
; =======
|
||||||
|
|
||||||
|
; Weed out `}`s that should not signal dedents.
|
||||||
|
(template_substitution "}" @_IGNORE_ (#set! capture.final true))
|
||||||
|
|
||||||
|
|
||||||
[
|
[
|
||||||
"{"
|
"{"
|
||||||
@ -27,5 +137,4 @@
|
|||||||
(type_arguments "<" @indent)
|
(type_arguments "<" @indent)
|
||||||
(type_arguments ">" @dedent)
|
(type_arguments ">" @dedent)
|
||||||
|
|
||||||
|
|
||||||
["case" "default"] @indent
|
["case" "default"] @indent
|
||||||
|
@ -38,3 +38,21 @@
|
|||||||
(#set! adjust.startAt lastChild.previousSibling.startPosition)
|
(#set! adjust.startAt lastChild.previousSibling.startPosition)
|
||||||
(#set! adjust.endAt lastChild.endPosition)
|
(#set! adjust.endAt lastChild.endPosition)
|
||||||
(#set! capture.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
|
|
||||||
|
; META
|
||||||
|
; ====
|
||||||
|
|
||||||
|
([
|
||||||
|
(jsx_opening_element)
|
||||||
|
(jsx_closing_element)
|
||||||
|
] @meta.jsx.inside-tag.ts.tsx
|
||||||
|
(#set! adjust.startAt firstChild.endPosition))
|
||||||
|
|
||||||
|
((jsx_self_closing_element) @meta.jsx.inside-tag.ts.tsx
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
|
||||||
|
((jsx_element) @meta.block.jsx.ts.tsx
|
||||||
|
(#set! adjust.startAt firstChild.endPosition)
|
||||||
|
(#set! adjust.endAt lastChild.startPosition))
|
||||||
|
@ -2,5 +2,7 @@
|
|||||||
; JSX
|
; JSX
|
||||||
; ===
|
; ===
|
||||||
|
|
||||||
(jsx_opening_element) @indent
|
(jsx_opening_element ["<" ">"] @indent)
|
||||||
(jsx_closing_element ">") @dedent
|
(jsx_opening_element [">"] @dedent)
|
||||||
|
|
||||||
|
(jsx_closing_element ">" @dedent)
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
exports.activate = function() {
|
exports.activate = function () {
|
||||||
for (const scopeName of ['source.ts', 'source.tsx', 'source.flow']) {
|
for (const scopeName of ['source.ts', 'source.tsx', 'source.flow']) {
|
||||||
|
atom.grammars.addInjectionPoint(scopeName, {
|
||||||
|
type: 'comment',
|
||||||
|
language(comment) {
|
||||||
|
if (comment.text.startsWith('/**')) return 'jsdoc';
|
||||||
|
},
|
||||||
|
content(comment) {
|
||||||
|
return comment;
|
||||||
|
},
|
||||||
|
languageScope: null,
|
||||||
|
// coverShallowerScopes: true
|
||||||
|
});
|
||||||
|
|
||||||
atom.grammars.addInjectionPoint(scopeName, {
|
atom.grammars.addInjectionPoint(scopeName, {
|
||||||
type: 'call_expression',
|
type: 'call_expression',
|
||||||
|
|
||||||
@ -53,9 +65,31 @@ exports.activate = function() {
|
|||||||
},
|
},
|
||||||
languageScope: null
|
languageScope: null
|
||||||
});
|
});
|
||||||
|
|
||||||
|
atom.grammars.addInjectionPoint(scopeName, {
|
||||||
|
type: 'comment',
|
||||||
|
language: (node) => {
|
||||||
|
return TODO_PATTERN.test(node.text) ? 'todo' : undefined;
|
||||||
|
},
|
||||||
|
content: (node) => node,
|
||||||
|
languageScope: null
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let type of ['template_string', 'string_fragment', 'comment']) {
|
||||||
|
atom.grammars.addInjectionPoint(scopeName, {
|
||||||
|
type,
|
||||||
|
language: (node) => {
|
||||||
|
return HYPERLINK_PATTERN.test(node.text) ? 'hyperlink' : undefined;
|
||||||
|
},
|
||||||
|
content: (node) => node,
|
||||||
|
languageScope: null
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TODO_PATTERN = /\b(TODO|FIXME|CHANGED|XXX|IDEA|HACK|NOTE|REVIEW|NB|BUG|QUESTION|COMBAK|TEMP|DEBUG|OPTIMIZE|WARNING)\b/;
|
||||||
|
const HYPERLINK_PATTERN = /\bhttps?:/
|
||||||
const STYLED_REGEX = /\bstyled\b/i;
|
const STYLED_REGEX = /\bstyled\b/i;
|
||||||
|
|
||||||
function languageStringForTemplateTag(tag) {
|
function languageStringForTemplateTag(tag) {
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
^ \\s* (\\s* /[*] .* [*]/ \\s*)* [}\\])]
|
^ \\s* (\\s* /[*] .* [*]/ \\s*)* [}\\])]
|
||||||
'
|
'
|
||||||
|
|
||||||
'.meta.tag.tsx':
|
'.meta.tag.tsx, .meta.block.jsx.ts.tsx':
|
||||||
'editor':
|
'editor':
|
||||||
'commentStart': '{/* ',
|
'commentStart': '{/* ',
|
||||||
'commentEnd': ' */}',
|
'commentEnd': ' */}',
|
||||||
'increaseIndentPattern': "{[^}\"']*$|\\[[^\\]\"']*$|\\([^)\"']*$|<[a-zA-Z][^/]*$|^\\s*>$",
|
'increaseIndentPattern': "{[^}\"']*$|\\[[^\\]\"']*$|\\([^)\"']*$|<[a-zA-Z][^/]*$|^\\s*>$",
|
||||||
'decreaseIndentPattern': "^\\s*(\\s*/[*].*[*]/\\s*)*[}\\])]|^\\s*(</|/>)"
|
'decreaseIndentPattern': "^\\s*(\\s*/[*].*[*]/\\s*)*[}\\])]|^\\s*(</|/>)"
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
(block_mapping_pair
|
(block_mapping_pair
|
||||||
key: (_) @entity.name.tag.yaml
|
key: (_) @entity.name.tag.yaml
|
||||||
(#set! test.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
(flow_pair
|
(flow_pair
|
||||||
key: (_) @entity.name.tag.yaml
|
key: (_) @entity.name.tag.yaml
|
||||||
(#set! test.final true))
|
(#set! capture.final true))
|
||||||
|
|
||||||
|
|
||||||
; COMMENTS
|
; COMMENTS
|
||||||
@ -35,6 +35,14 @@
|
|||||||
|
|
||||||
((string_scalar) @string.quoted.yaml)
|
((string_scalar) @string.quoted.yaml)
|
||||||
|
|
||||||
|
(single_quote_scalar) @string.quoted.single.yaml
|
||||||
|
|
||||||
|
((single_quote_scalar) @punctuation.definition.string.begin.yaml
|
||||||
|
(#set! adjust.endAfterFirstMatchOf "^'"))
|
||||||
|
|
||||||
|
((single_quote_scalar) @punctuation.definition.string.end.yaml
|
||||||
|
(#set! adjust.startBeforeFirstMatchOf "'$"))
|
||||||
|
|
||||||
(double_quote_scalar) @string.quoted.double.yaml
|
(double_quote_scalar) @string.quoted.double.yaml
|
||||||
|
|
||||||
((double_quote_scalar) @punctuation.definition.string.begin.yaml
|
((double_quote_scalar) @punctuation.definition.string.begin.yaml
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
(":" @indent
|
(":" @indent
|
||||||
(#set! test.onlyIfLastTextOnRow true))
|
(#is? test.lastTextOnRow true))
|
||||||
|
|
||||||
["|" ">"] @indent
|
["|" ">"] @indent
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
(block_mapping_pair
|
(block_mapping_pair
|
||||||
key: (_) @name
|
key: (_) @name
|
||||||
(#set! test.final true)
|
(#set! capture.final true)
|
||||||
(#set! symbol.prependSymbolForNode parent.parent.parent.parent.parent.parent.parent.firstNamedChild)
|
(#set! symbol.prependSymbolForNode parent.parent.parent.parent.parent.parent.parent.firstNamedChild)
|
||||||
(#set! symbol.joiner "."))
|
(#set! symbol.joiner "."))
|
||||||
|
@ -228,7 +228,7 @@ describe('ScopeResolver', () => {
|
|||||||
let bar = "this is a line below a comment"
|
let bar = "this is a line below a comment"
|
||||||
`);
|
`);
|
||||||
// Prevent an exception from being thrown before we can even check the
|
// Prevent an exception from being thrown before we can even check the
|
||||||
// scopeResovler.
|
// scopeResolver.
|
||||||
spyOn(languageMode, 'isRowCommented').andReturn(false);
|
spyOn(languageMode, 'isRowCommented').andReturn(false);
|
||||||
await languageMode.ready;
|
await languageMode.ready;
|
||||||
|
|
||||||
|
@ -16,6 +16,11 @@ function comparePoints(a, b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rangeSpecToString (range) {
|
||||||
|
let [sp, ep] = [range.startPosition, range.endPosition];
|
||||||
|
return `(${sp.row}, ${sp.column}) - (${ep.row}, ${ep.column})`;
|
||||||
|
}
|
||||||
|
|
||||||
function resolveNodeDescriptor(node, descriptor) {
|
function resolveNodeDescriptor(node, descriptor) {
|
||||||
let parts = descriptor.split('.');
|
let parts = descriptor.split('.');
|
||||||
let result = node;
|
let result = node;
|
||||||
@ -266,6 +271,20 @@ class ScopeResolver {
|
|||||||
return ScopeResolver.CAPTURE_SETTINGS[prop](...args);
|
return ScopeResolver.CAPTURE_SETTINGS[prop](...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
warnAboutExceededRange(range, capture) {
|
||||||
|
let msg = ['Cannot extend past original range of capture!'];
|
||||||
|
|
||||||
|
msg.push(`Scope name: ${capture.name}`);
|
||||||
|
msg.push(`Original range: ${rangeSpecToString(capture.node)}`);
|
||||||
|
msg.push(`Adjusted range: ${rangeSpecToString(range)}`);
|
||||||
|
|
||||||
|
if (atom.inDevMode()) {
|
||||||
|
throw new Error(msg.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(msg.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
// Given a capture and possible predicate data, determines the buffer range
|
// Given a capture and possible predicate data, determines the buffer range
|
||||||
// that this capture wants to cover.
|
// that this capture wants to cover.
|
||||||
determineCaptureRange(capture) {
|
determineCaptureRange(capture) {
|
||||||
@ -299,7 +318,7 @@ class ScopeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.rangeExceedsBoundsOfCapture(range, capture)) {
|
if (this.rangeExceedsBoundsOfCapture(range, capture)) {
|
||||||
throw new Error('Cannot extend past original range of capture');
|
this.warnAboutExceededRange(range, capture);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any invalidity in the returned range means we shouldn't store this
|
// Any invalidity in the returned range means we shouldn't store this
|
||||||
|
@ -45,6 +45,8 @@ module.exports = class WASMTreeSitterGrammar {
|
|||||||
commentEndString: params.comments && params.comments.end
|
commentEndString: params.comments && params.comments.end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.commentMetadata = params.comments;
|
||||||
|
|
||||||
this.shouldObserveQueryFiles = atom.inDevMode() && !atom.inSpecMode();
|
this.shouldObserveQueryFiles = atom.inDevMode() && !atom.inSpecMode();
|
||||||
this.getLanguage();
|
this.getLanguage();
|
||||||
|
|
||||||
@ -69,6 +71,50 @@ module.exports = class WASMTreeSitterGrammar {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve the comment delimiters for this grammar.
|
||||||
|
//
|
||||||
|
// Traditionally, grammars specified only the delimiters needed for the
|
||||||
|
// “Toggle Line Comments” command — either a line comment (if it existed) or
|
||||||
|
// a block comment. But other features might want to know _all_ of a
|
||||||
|
// language's possible comment delimiters, so we've devised new config values.
|
||||||
|
getCommentDelimiters() {
|
||||||
|
let meta = this.commentMetadata;
|
||||||
|
if (!meta) { return null; }
|
||||||
|
|
||||||
|
let result = {};
|
||||||
|
|
||||||
|
// The new convention is to specify a `line` property and start/end
|
||||||
|
// properties.
|
||||||
|
let { line, block } = this.commentMetadata;
|
||||||
|
|
||||||
|
// Failing that, we can deliver at least a partial result by inspecting the
|
||||||
|
// older convention. If `start` exists but not `end`, we know `start` must
|
||||||
|
// be a line comment delimiter.
|
||||||
|
if (!line && meta.start && !meta.end) {
|
||||||
|
line = meta.start;
|
||||||
|
}
|
||||||
|
// Likewise, if both `start` and `end` exist, we know they must be block
|
||||||
|
// comment delimiters.
|
||||||
|
if (!block && meta.start && meta.end) {
|
||||||
|
block = { start: meta.start, end: meta.end };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip all whitespace from delimiters. Whatever is consuming them can
|
||||||
|
// decide if it wants whitespace.
|
||||||
|
if (line) {
|
||||||
|
line = line.strip();
|
||||||
|
result.line = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
block.start = block.start?.strip();
|
||||||
|
block.end = block.end?.strip();
|
||||||
|
result.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
classNameForScopeId(id) {
|
classNameForScopeId(id) {
|
||||||
return this.classNamesById.get(id);
|
return this.classNamesById.get(id);
|
||||||
}
|
}
|
||||||
@ -127,7 +173,7 @@ module.exports = class WASMTreeSitterGrammar {
|
|||||||
this.observeQueryFile(filePaths, key);
|
this.observeQueryFile(filePaths, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Promise.all(promises).then(() => resolve());
|
return Promise.all(promises).then(() => resolve());
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this._queryFilesLoaded = true;
|
this._queryFilesLoaded = true;
|
||||||
this._loadQueryFilesPromise = null;
|
this._loadQueryFilesPromise = null;
|
||||||
@ -254,7 +300,9 @@ module.exports = class WASMTreeSitterGrammar {
|
|||||||
await this.getLanguage();
|
await this.getLanguage();
|
||||||
this.queryCache.delete(queryType);
|
this.queryCache.delete(queryType);
|
||||||
this[queryType] = contents;
|
this[queryType] = contents;
|
||||||
return await this.getQuery(queryType);
|
let query = await this.getQuery(queryType);
|
||||||
|
this.emitter.emit('did-change-query-file', { filePath: '', queryType });
|
||||||
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Observe a particular query file on disk so that it can immediately be
|
// Observe a particular query file on disk so that it can immediately be
|
||||||
|
@ -1056,19 +1056,42 @@ class WASMTreeSitterLanguageMode {
|
|||||||
Section - Comments
|
Section - Comments
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: I know that old tree-sitter moved toward placing this data on the
|
// Returns the correct comment delimiters for the given buffer position. This
|
||||||
// grammar itself, but I would prefer to invert the order of these lookups.
|
// may be defined on the grammar itself, but it can also be defined as a
|
||||||
// As a config setting it can be scoped and overridden, but as a grammar
|
// scope-specific setting for scenarios where a language has different
|
||||||
// property it's just a fact of life that can't be worked around.
|
// comment delimiters for different contexts.
|
||||||
//
|
|
||||||
// TODO: Also, this should be revisited soon so that we can give the
|
|
||||||
// `snippets` package the ability to ask about all of a grammar's comment
|
|
||||||
// tokens — both line and block.
|
|
||||||
//
|
//
|
||||||
|
// TODO: Our understanding of the correct delimiters for a given buffer
|
||||||
|
// position is only as granular as the entire buffer row. This can bite us in
|
||||||
|
// edge cases like JSX. It's the right decision if the user toggles a comment
|
||||||
|
// with an empty selection, but if specific buffer text is selected, we
|
||||||
|
// should look up the right delmiters for that specific range. This will
|
||||||
|
// require a new branch in the “Editor: Toggle Line Comments” command.
|
||||||
commentStringsForPosition(position) {
|
commentStringsForPosition(position) {
|
||||||
// First ask the grammar for its comment strings.
|
|
||||||
const range = this.firstNonWhitespaceRange(position.row) ||
|
const range = this.firstNonWhitespaceRange(position.row) ||
|
||||||
new Range(position, position);
|
new Range(position, position);
|
||||||
|
|
||||||
|
// Ask the config system if it has a setting for this scope. This allows
|
||||||
|
// for overrides from the grammar default.
|
||||||
|
const scope = this.scopeDescriptorForPosition(range.start);
|
||||||
|
const commentStartEntries = this.config.getAll(
|
||||||
|
'editor.commentStart', { scope });
|
||||||
|
const commentEndEntries = this.config.getAll(
|
||||||
|
'editor.commentEnd', { scope });
|
||||||
|
|
||||||
|
const commentStartEntry = commentStartEntries[0];
|
||||||
|
const commentEndEntry = commentEndEntries.find(entry => (
|
||||||
|
entry.scopeSelector === commentStartEntry.scopeSelector
|
||||||
|
));
|
||||||
|
|
||||||
|
if (commentStartEntry) {
|
||||||
|
return {
|
||||||
|
commentStartString: commentStartEntry && commentStartEntry.value,
|
||||||
|
commentEndString: commentEndEntry && commentEndEntry.value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to looking up this information on the grammar.
|
||||||
const { grammar } = this.getSyntaxNodeAndGrammarContainingRange(range);
|
const { grammar } = this.getSyntaxNodeAndGrammarContainingRange(range);
|
||||||
|
|
||||||
if (grammar) {
|
if (grammar) {
|
||||||
@ -1079,22 +1102,6 @@ class WASMTreeSitterLanguageMode {
|
|||||||
return commentStrings;
|
return commentStrings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to a lookup through the config system.
|
|
||||||
const scope = this.scopeDescriptorForPosition(position);
|
|
||||||
const commentStartEntries = this.config.getAll(
|
|
||||||
'editor.commentStart', { scope });
|
|
||||||
const commentEndEntries = this.config.getAll(
|
|
||||||
'editor.commentEnd', { scope });
|
|
||||||
|
|
||||||
const commentStartEntry = commentStartEntries[0];
|
|
||||||
const commentEndEntry = commentEndEntries.find(entry => (
|
|
||||||
entry.scopeSelector === commentStartEntry.scopeSelector
|
|
||||||
));
|
|
||||||
return {
|
|
||||||
commentStartString: commentStartEntry && commentStartEntry.value,
|
|
||||||
commentEndString: commentEndEntry && commentEndEntry.value
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isRowCommented(row) {
|
isRowCommented(row) {
|
||||||
@ -1124,7 +1131,7 @@ class WASMTreeSitterLanguageMode {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return indentLength / tabLength;
|
return Math.floor(indentLength / tabLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the suggested indentation level for an existing line in the buffer.
|
// Get the suggested indentation level for an existing line in the buffer.
|
||||||
@ -1642,6 +1649,11 @@ class WASMTreeSitterLanguageMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!indentTree) {
|
||||||
|
console.error(`No indent tree!`, controllingLayer.inspect());
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const indents = indentsQuery.captures(
|
const indents = indentsQuery.captures(
|
||||||
indentTree.rootNode,
|
indentTree.rootNode,
|
||||||
{ row: row, column: 0 },
|
{ row: row, column: 0 },
|
||||||
@ -2821,10 +2833,10 @@ class GrammarLoadError extends Error {
|
|||||||
constructor(grammar, queryType) {
|
constructor(grammar, queryType) {
|
||||||
super(`Grammar ${grammar.scopeName} failed to load its ${queryType}. Please fix this error or contact the maintainer.`);
|
super(`Grammar ${grammar.scopeName} failed to load its ${queryType}. Please fix this error or contact the maintainer.`);
|
||||||
this.name = 'GrammarLoadError';
|
this.name = 'GrammarLoadError';
|
||||||
|
this.queryType = queryType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Manages all aspects of a given language's parsing duties over a given region
|
// Manages all aspects of a given language's parsing duties over a given region
|
||||||
// of the buffer.
|
// of the buffer.
|
||||||
//
|
//
|
||||||
@ -2898,6 +2910,13 @@ class LanguageLayer {
|
|||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
if (err.name === 'GrammarLoadError') {
|
if (err.name === 'GrammarLoadError') {
|
||||||
console.warn(err.message);
|
console.warn(err.message);
|
||||||
|
if (err.queryType === 'highlightsQuery') {
|
||||||
|
// TODO: Warning?
|
||||||
|
grammar.highlightsQuery = grammar.setQueryForTest(
|
||||||
|
'highlightsQuery',
|
||||||
|
`; (placeholder)`
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -2921,12 +2940,17 @@ class LanguageLayer {
|
|||||||
if (depth === 0) {
|
if (depth === 0) {
|
||||||
languageScope = this.grammar.scopeName;
|
languageScope = this.grammar.scopeName;
|
||||||
} else {
|
} else {
|
||||||
|
// Injections can control the base scope name of the grammar being
|
||||||
|
// injected.
|
||||||
languageScope = injectionPoint.languageScope;
|
languageScope = injectionPoint.languageScope;
|
||||||
// Honor an explicit `null`, but fall back to the default scope name
|
|
||||||
// otherwise.
|
// The `languageScope` parameter can be a function.
|
||||||
if (typeof languageScope === 'function') {
|
if (typeof languageScope === 'function') {
|
||||||
languageScope = languageScope(this.grammar);
|
languageScope = languageScope(this.grammar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Honor an explicit `null`, but fall back to the default scope name
|
||||||
|
// otherwise.
|
||||||
if (languageScope === undefined) {
|
if (languageScope === undefined) {
|
||||||
languageScope = this.grammar.scopeName;
|
languageScope = this.grammar.scopeName;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user