mirror of
https://github.com/atom/atom.git
synced 2026-01-26 15:28:27 -05:00
Fix a ruby folding issue
This commit is contained in:
@@ -13,6 +13,7 @@ class TreeSitterGrammar {
|
||||
if (params.injectionRegExp) this.injectionRegExp = new RegExp(params.injectionRegExp)
|
||||
|
||||
this.folds = params.folds || []
|
||||
this.folds.forEach(normalizeFoldSpecification)
|
||||
|
||||
this.commentStrings = {
|
||||
commentStartString: params.comments && params.comments.start,
|
||||
@@ -72,3 +73,36 @@ class TreeSitterGrammar {
|
||||
if (this.registration) this.registration.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
const NODE_NAME_REGEX = /[\w_]+/
|
||||
|
||||
function matcherForSpec (spec) {
|
||||
if (typeof spec === 'string') {
|
||||
if (spec[0] === '"' && spec[spec.length - 1] === '"') {
|
||||
return {
|
||||
type: spec.substr(1, spec.length - 2),
|
||||
named: false
|
||||
}
|
||||
}
|
||||
|
||||
if (!NODE_NAME_REGEX.test(spec)) {
|
||||
return {type: spec, named: false}
|
||||
}
|
||||
|
||||
return {type: spec, named: true}
|
||||
}
|
||||
return spec
|
||||
}
|
||||
|
||||
function normalizeFoldSpecification (spec) {
|
||||
if (spec.type) {
|
||||
if (Array.isArray(spec.type)) {
|
||||
spec.matchers = spec.type.map(matcherForSpec)
|
||||
} else {
|
||||
spec.matchers = [matcherForSpec(spec.type)]
|
||||
}
|
||||
}
|
||||
|
||||
if (spec.start) normalizeFoldSpecification(spec.start)
|
||||
if (spec.end) normalizeFoldSpecification(spec.end)
|
||||
}
|
||||
|
||||
@@ -269,42 +269,32 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
|
||||
getFoldableRangeForNode (node, grammar, existenceOnly) {
|
||||
const {children, type: nodeType} = node
|
||||
const {children} = node
|
||||
const childCount = children.length
|
||||
let childTypes
|
||||
|
||||
for (var i = 0, {length} = grammar.folds; i < length; i++) {
|
||||
const foldEntry = grammar.folds[i]
|
||||
const foldSpec = grammar.folds[i]
|
||||
|
||||
if (foldEntry.type) {
|
||||
if (typeof foldEntry.type === 'string') {
|
||||
if (foldEntry.type !== nodeType) continue
|
||||
} else {
|
||||
if (!foldEntry.type.includes(nodeType)) continue
|
||||
}
|
||||
}
|
||||
if (foldSpec.matchers && !hasMatchingFoldSpec(foldSpec.matchers, node)) continue
|
||||
|
||||
let foldStart
|
||||
const startEntry = foldEntry.start
|
||||
const startEntry = foldSpec.start
|
||||
if (startEntry) {
|
||||
let foldStartNode
|
||||
if (startEntry.index != null) {
|
||||
const child = children[startEntry.index]
|
||||
if (!child || (startEntry.type && startEntry.type !== child.type)) continue
|
||||
foldStart = child.endPosition
|
||||
foldStartNode = children[startEntry.index]
|
||||
if (!foldStartNode || startEntry.matchers && !hasMatchingFoldSpec(startEntry.matchers, foldStartNode)) continue
|
||||
} else {
|
||||
if (!childTypes) childTypes = children.map(child => child.type)
|
||||
const index = typeof startEntry.type === 'string'
|
||||
? childTypes.indexOf(startEntry.type)
|
||||
: childTypes.findIndex(type => startEntry.type.includes(type))
|
||||
if (index === -1) continue
|
||||
foldStart = children[index].endPosition
|
||||
foldStartNode = children.find(child => hasMatchingFoldSpec(startEntry.matchers, child))
|
||||
if (!foldStartNode) continue
|
||||
}
|
||||
foldStart = new Point(foldStartNode.endPosition.row, Infinity)
|
||||
} else {
|
||||
foldStart = new Point(node.startPosition.row, Infinity)
|
||||
}
|
||||
|
||||
let foldEnd
|
||||
const endEntry = foldEntry.end
|
||||
const endEntry = foldSpec.end
|
||||
if (endEntry) {
|
||||
let foldEndNode
|
||||
if (endEntry.index != null) {
|
||||
@@ -312,12 +302,8 @@ class TreeSitterLanguageMode {
|
||||
foldEndNode = children[index]
|
||||
if (!foldEndNode || (endEntry.type && endEntry.type !== foldEndNode.type)) continue
|
||||
} else {
|
||||
if (!childTypes) childTypes = children.map(foldEndNode => foldEndNode.type)
|
||||
const index = typeof endEntry.type === 'string'
|
||||
? childTypes.indexOf(endEntry.type)
|
||||
: childTypes.findIndex(type => endEntry.type.includes(type))
|
||||
if (index === -1) continue
|
||||
foldEndNode = children[index]
|
||||
foldEndNode = children.find(child => hasMatchingFoldSpec(endEntry.matchers, child))
|
||||
if (!foldEndNode) continue
|
||||
}
|
||||
|
||||
if (foldEndNode.endIndex - foldEndNode.startIndex > 1 && foldEndNode.startPosition.row > foldStart.row) {
|
||||
@@ -768,7 +754,12 @@ class LayerHighlightIterator {
|
||||
} else {
|
||||
this.atEnd = false
|
||||
this.openTags.push(id)
|
||||
const {startIndex} = this.treeCursor
|
||||
while (this.treeCursor.gotoFirstChild()) {
|
||||
if (this.treeCursor.startIndex > startIndex) {
|
||||
this.treeCursor.gotoParent()
|
||||
break
|
||||
}
|
||||
this.containingNodeTypes.push(this.treeCursor.nodeType)
|
||||
this.containingNodeChildIndices.push(0)
|
||||
const scopeName = this.currentScopeName()
|
||||
@@ -1041,6 +1032,10 @@ function last (array) {
|
||||
return array[array.length - 1]
|
||||
}
|
||||
|
||||
function hasMatchingFoldSpec (specs, node) {
|
||||
return specs.some(({type, named}) => type === node.type && named === node.isNamed)
|
||||
}
|
||||
|
||||
// TODO: Remove this once TreeSitterLanguageMode implements its own auto-indent system.
|
||||
[
|
||||
'_suggestedIndentForLineWithScopeAtBufferRow',
|
||||
|
||||
Reference in New Issue
Block a user