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