mirror of
https://github.com/atom/atom.git
synced 2026-02-19 02:44:29 -05:00
🐎 Parse asynchronously when opening buffers
This commit is contained in:
@@ -662,27 +662,35 @@ class Project extends Model {
|
||||
// * `text` The {String} text to use as a buffer.
|
||||
//
|
||||
// Returns a {Promise} that resolves to the {TextBuffer}.
|
||||
buildBuffer (absoluteFilePath) {
|
||||
async buildBuffer (absoluteFilePath) {
|
||||
const params = {shouldDestroyOnFileDelete: this.shouldDestroyBufferOnFileDelete}
|
||||
|
||||
let promise
|
||||
let buffer
|
||||
if (absoluteFilePath != null) {
|
||||
if (this.loadPromisesByPath[absoluteFilePath] == null) {
|
||||
this.loadPromisesByPath[absoluteFilePath] =
|
||||
TextBuffer.load(absoluteFilePath, params).catch(error => {
|
||||
delete this.loadPromisesByPath[absoluteFilePath]
|
||||
throw error
|
||||
})
|
||||
TextBuffer.load(absoluteFilePath, params)
|
||||
.then(result => {
|
||||
delete this.loadPromisesByPath[absoluteFilePath]
|
||||
return result
|
||||
})
|
||||
.catch(error => {
|
||||
delete this.loadPromisesByPath[absoluteFilePath]
|
||||
throw error
|
||||
})
|
||||
}
|
||||
promise = this.loadPromisesByPath[absoluteFilePath]
|
||||
buffer = await this.loadPromisesByPath[absoluteFilePath]
|
||||
} else {
|
||||
promise = Promise.resolve(new TextBuffer(params))
|
||||
buffer = new TextBuffer(params)
|
||||
}
|
||||
return promise.then(buffer => {
|
||||
delete this.loadPromisesByPath[absoluteFilePath]
|
||||
this.addBuffer(buffer)
|
||||
return buffer
|
||||
})
|
||||
|
||||
this.grammarRegistry.autoAssignLanguageMode(buffer)
|
||||
if (buffer.languageMode.initialize) {
|
||||
await buffer.languageMode.initialize()
|
||||
}
|
||||
|
||||
this.addBuffer(buffer)
|
||||
return buffer
|
||||
}
|
||||
|
||||
addBuffer (buffer, options = {}) {
|
||||
|
||||
@@ -16,7 +16,7 @@ class TreeSitterLanguageMode {
|
||||
this.config = config
|
||||
this.parser = new Parser()
|
||||
this.parser.setLanguage(grammar.languageModule)
|
||||
this.tree = this.parser.parseTextBufferSync(this.buffer.buffer)
|
||||
this.tree = null
|
||||
this.rootScopeDescriptor = new ScopeDescriptor({scopes: [this.grammar.id]})
|
||||
this.emitter = new Emitter()
|
||||
this.isFoldableCache = []
|
||||
@@ -35,11 +35,22 @@ class TreeSitterLanguageMode {
|
||||
this.regexesByPattern = {}
|
||||
}
|
||||
|
||||
async initialize () {
|
||||
this.tree = await this.parser.parseTextBuffer(this.buffer.buffer)
|
||||
}
|
||||
|
||||
ensureParseTree () {
|
||||
if (!this.tree) {
|
||||
this.tree = this.parser.parseTextBufferSync(this.buffer.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
getLanguageId () {
|
||||
return this.grammar.id
|
||||
}
|
||||
|
||||
bufferDidChange (change) {
|
||||
this.ensureParseTree()
|
||||
const {oldRange, newRange} = change
|
||||
const startRow = oldRange.start.row
|
||||
const oldEndRow = oldRange.end.row
|
||||
@@ -93,7 +104,8 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
|
||||
buildHighlightIterator () {
|
||||
return new TreeSitterHighlightIterator(this)
|
||||
this.ensureParseTree()
|
||||
return new TreeSitterHighlightIterator(this, this.tree.walk())
|
||||
}
|
||||
|
||||
onDidChangeHighlighting (callback) {
|
||||
@@ -170,6 +182,7 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
|
||||
getFoldableRangesAtIndentLevel (goalLevel) {
|
||||
this.ensureParseTree()
|
||||
let result = []
|
||||
let stack = [{node: this.tree.rootNode, level: 0}]
|
||||
while (stack.length > 0) {
|
||||
@@ -215,6 +228,7 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
|
||||
getFoldableRangeContainingPoint (point, tabLength, existenceOnly = false) {
|
||||
this.ensureParseTree()
|
||||
let node = this.tree.rootNode.descendantForPosition(this.buffer.clipPosition(point))
|
||||
while (node) {
|
||||
if (existenceOnly && node.startPosition.row < point.row) break
|
||||
@@ -335,8 +349,8 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
|
||||
scopeDescriptorForPosition (point) {
|
||||
this.ensureParseTree()
|
||||
point = Point.fromObject(point)
|
||||
const result = []
|
||||
let node = this.tree.rootNode.descendantForPosition(point)
|
||||
|
||||
// Don't include anonymous token types like '(' because they prevent scope chains
|
||||
@@ -345,6 +359,7 @@ class TreeSitterLanguageMode {
|
||||
// selectors.
|
||||
if (!node.isNamed) node = node.parent
|
||||
|
||||
const result = []
|
||||
while (node) {
|
||||
result.push(node.type)
|
||||
node = node.parent
|
||||
@@ -363,9 +378,9 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
|
||||
class TreeSitterHighlightIterator {
|
||||
constructor (layer) {
|
||||
constructor (layer, treeCursor) {
|
||||
this.layer = layer
|
||||
this.treeCursor = this.layer.tree.walk()
|
||||
this.treeCursor = treeCursor
|
||||
|
||||
// In order to determine which selectors match its current node, the iterator maintains
|
||||
// a list of the current node's ancestors. Because the selectors can use the `:nth-child`
|
||||
|
||||
Reference in New Issue
Block a user