Don’t use atom.grammars global in TokenizedBuffer

This commit is contained in:
Nathan Sobo
2015-10-03 11:13:38 -06:00
parent 4f65452902
commit b2359f44a6
10 changed files with 80 additions and 47 deletions

View File

@@ -7,7 +7,9 @@ describe "DisplayBuffer", ->
tabLength = 2
buffer = atom.project.bufferForPathSync('sample.js')
displayBuffer = new DisplayBuffer({buffer, tabLength, config: atom.config, assert: ->})
displayBuffer = new DisplayBuffer({
buffer, tabLength, config: atom.config, grammarRegistry: atom.grammars, assert: ->
})
changeHandler = jasmine.createSpy 'changeHandler'
displayBuffer.onDidChange changeHandler
@@ -49,7 +51,9 @@ describe "DisplayBuffer", ->
it "updates the display buffer prior to invoking change handlers registered on the buffer", ->
buffer.onDidChange -> expect(displayBuffer2.tokenizedLineForScreenRow(0).text).toBe "testing"
displayBuffer2 = new DisplayBuffer({buffer, tabLength, config: atom.config, assert: ->})
displayBuffer2 = new DisplayBuffer({
buffer, tabLength, config: atom.config, grammarRegistry: atom.grammars, assert: ->
})
buffer.setText("testing")
describe "soft wrapping", ->
@@ -232,7 +236,10 @@ describe "DisplayBuffer", ->
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
it "correctly renders the original wrapped line", ->
buffer = atom.project.buildBufferSync(null, '')
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, config: atom.config, assert: ->})
displayBuffer = new DisplayBuffer({
buffer, tabLength, editorWidthInChars: 30, config: atom.config,
grammarRegistry: atom.grammars, assert: ->
})
displayBuffer.setSoftWrapped(true)
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
@@ -294,7 +301,9 @@ describe "DisplayBuffer", ->
displayBuffer.destroy()
buffer.release()
buffer = atom.project.bufferForPathSync('two-hundred.txt')
displayBuffer = new DisplayBuffer({buffer, tabLength, config: atom.config, assert: ->})
displayBuffer = new DisplayBuffer({
buffer, tabLength, config: atom.config, grammarRegistry: atom.grammars, assert: ->
})
displayBuffer.onDidChange changeHandler
describe "when folds are created and destroyed", ->
@@ -408,7 +417,9 @@ describe "DisplayBuffer", ->
describe "when there is another display buffer pointing to the same buffer", ->
it "does not consider folds to be nested inside of folds from the other display buffer", ->
otherDisplayBuffer = new DisplayBuffer({buffer, tabLength, config: atom.config, assert: ->})
otherDisplayBuffer = new DisplayBuffer({
buffer, tabLength, config: atom.config, grammarRegistry: atom.grammars, assert: ->
})
otherDisplayBuffer.createFold(1, 5)
displayBuffer.createFold(2, 4)
@@ -1154,7 +1165,9 @@ describe "DisplayBuffer", ->
describe 'when there are multiple DisplayBuffers for a buffer', ->
describe 'when a marker is created', ->
it 'the second display buffer will not emit a marker-created event when the marker has been deleted in the first marker-created event', ->
displayBuffer2 = new DisplayBuffer({buffer, tabLength, config: atom.config, assert: ->})
displayBuffer2 = new DisplayBuffer({
buffer, tabLength, config: atom.config, grammarRegistry: atom.grammars, assert: ->
})
displayBuffer.onDidCreateMarker markerCreated1 = jasmine.createSpy().andCallFake (marker) -> marker.destroy()
displayBuffer2.onDidCreateMarker markerCreated2 = jasmine.createSpy()

View File

@@ -92,7 +92,8 @@ beforeEach ->
grammarRegistry: atom.grammars, notificationManager: atom.notifications,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: atom.setDocumentEdited.bind(atom), atomVersion: atom.getVersion(),
clipboard: atom.clipboard, viewRegistry: atom.views, assert: atom.assert.bind(atom)
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
assert: atom.assert.bind(atom)
})
atom.themes.workspace = atom.workspace
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)

View File

@@ -24,7 +24,7 @@ describe "TokenIterator", ->
end x
x
""")
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
tokenizedBuffer.setGrammar(grammar)
tokenIterator = tokenizedBuffer.tokenizedLineForRow(1).getTokenIterator()

View File

@@ -27,7 +27,7 @@ describe "TokenizedBuffer", ->
describe "when the buffer is destroyed", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
startTokenizing(tokenizedBuffer)
it "stops tokenization", ->
@@ -39,7 +39,7 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains soft-tabs", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
startTokenizing(tokenizedBuffer)
tokenizedBuffer.onDidChange changeHandler = jasmine.createSpy('changeHandler')
@@ -345,7 +345,7 @@ describe "TokenizedBuffer", ->
runs ->
buffer = atom.project.bufferForPathSync('sample-with-tabs.coffee')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
startTokenizing(tokenizedBuffer)
afterEach ->
@@ -450,7 +450,7 @@ describe "TokenizedBuffer", ->
'abc\uD835\uDF97def'
//\uD835\uDF97xyz
"""
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
afterEach ->
@@ -544,7 +544,7 @@ describe "TokenizedBuffer", ->
runs ->
buffer = atom.project.bufferForPathSync()
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
tokenizedBuffer.setGrammar(atom.grammars.selectGrammar('test.erb'))
fullyTokenize(tokenizedBuffer)
@@ -566,7 +566,7 @@ describe "TokenizedBuffer", ->
it "returns the correct token (regression)", ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([1, 0]).scopes).toEqual ["source.js"]
expect(tokenizedBuffer.tokenForPosition([1, 1]).scopes).toEqual ["source.js"]
@@ -575,7 +575,7 @@ describe "TokenizedBuffer", ->
describe ".bufferRangeForScopeAtPosition(selector, position)", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
describe "when the selector does not match the token at the position", ->
@@ -595,7 +595,7 @@ describe "TokenizedBuffer", ->
it "updates the tab length of the tokenized lines", ->
buffer = atom.project.bufferForPathSync('sample.js')
buffer.setText('\ttest')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([0, 0]).value).toBe ' '
atom.config.set('editor.tabLength', 6)
@@ -604,7 +604,7 @@ describe "TokenizedBuffer", ->
it "does not allow the tab length to be less than 1", ->
buffer = atom.project.bufferForPathSync('sample.js')
buffer.setText('\ttest')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([0, 0]).value).toBe ' '
atom.config.set('editor.tabLength', 1)
@@ -617,7 +617,7 @@ describe "TokenizedBuffer", ->
it "updates the tokens with the appropriate invisible characters", ->
buffer = new TextBuffer(text: " \t a line with tabs\tand \tspaces \t ")
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
atom.config.set("editor.showInvisibles", true)
@@ -630,7 +630,7 @@ describe "TokenizedBuffer", ->
it "assigns endOfLineInvisibles to tokenized lines", ->
buffer = new TextBuffer(text: "a line that ends in a carriage-return-line-feed \r\na line that ends in just a line-feed\na line with no ending")
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
atom.config.set('editor.showInvisibles', true)
atom.config.set("editor.invisibles", cr: 'R', eol: 'N')
@@ -651,7 +651,7 @@ describe "TokenizedBuffer", ->
describe "leading and trailing whitespace", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
it "assigns ::firstNonWhitespaceIndex on tokens that have leading whitespace", ->
@@ -709,7 +709,7 @@ describe "TokenizedBuffer", ->
describe ".indentLevel on tokenized lines", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
describe "when the line is non-empty", ->
@@ -804,7 +804,7 @@ describe "TokenizedBuffer", ->
buffer = atom.project.bufferForPathSync('sample.js')
buffer.insert [10, 0], " // multi-line\n // comment\n // block\n"
buffer.insert [0, 0], "// multi-line\n// comment\n// block\n"
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
fullyTokenize(tokenizedBuffer)
tokenizedBuffer.onDidChange (change) ->
delete change.bufferChange
@@ -881,7 +881,7 @@ describe "TokenizedBuffer", ->
buffer = atom.project.bufferForPathSync('sample.will-use-the-null-grammar')
buffer.setText('a\nb\nc')
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config})
tokenizedBuffer = new TokenizedBuffer({buffer, config: atom.config, grammarRegistry: atom.grammars})
tokenizeCallback = jasmine.createSpy('onDidTokenize')
tokenizedBuffer.onDidTokenize(tokenizeCallback)

View File

@@ -17,7 +17,7 @@ describe "Workspace", ->
atom.workspace = workspace = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
grammarRegistry: atom.grammars, notificationManager: atom.notifications,
clipboard: atom.clipboard, viewRegistry: atom.views,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, atomVersion: atom.getVersion(),
assert: atom.assert.bind(atom)
@@ -35,7 +35,7 @@ describe "Workspace", ->
atom.workspace = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
grammarRegistry: atom.grammars, notificationManager: atom.notifications,
clipboard: atom.clipboard, viewRegistry: atom.views,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, assert: atom.assert.bind(atom)
})
@@ -634,7 +634,7 @@ describe "Workspace", ->
workspace2 = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
grammarRegistry: atom.grammars, notificationManager: atom.notifications,
clipboard: atom.clipboard, viewRegistry: atom.views,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, atomVersion: atom.getVersion(),
assert: atom.assert.bind(atom)
@@ -694,7 +694,7 @@ describe "Workspace", ->
workspace2 = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
grammarRegistry: atom.grammars, notificationManager: atom.notifications,
clipboard: atom.clipboard, viewRegistry: atom.views,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
setRepresentedFilename: jasmine.createSpy('setRepresentedFilename'),
setDocumentEdited: setDocumentEdited, atomVersion: atom.getVersion(),
assert: atom.assert.bind(atom)

View File

@@ -176,7 +176,7 @@ class Atom extends Model
@config, @project, packageManager: @packages, grammarRegistry: @grammars,
notificationManager: @notifications, setRepresentedFilename: @setRepresentedFilename.bind(this),
setDocumentEdited: @setDocumentEdited.bind(this), @clipboard, viewRegistry: @views,
assert: @assert.bind(this)
grammarRegistry: @grammars, assert: @assert.bind(this)
})
@themes.workspace = @workspace

View File

@@ -31,16 +31,22 @@ class DisplayBuffer extends Model
state.tokenizedBuffer = TokenizedBuffer.deserialize(state.tokenizedBuffer, atomEnvironment)
state.config = atomEnvironment.config
state.assert = atomEnvironment.assert
state.grammarRegistry = atomEnvironment.grammars
new this(state)
constructor: ({tabLength, @editorWidthInChars, @tokenizedBuffer, buffer, ignoreInvisibles, @largeFileMode, @config, @assert}={}) ->
constructor: (params={}) ->
super
{
tabLength, @editorWidthInChars, @tokenizedBuffer, buffer, ignoreInvisibles,
@largeFileMode, @config, @assert, @grammarRegistry
} = params
@emitter = new Emitter
@disposables = new CompositeDisposable
@tokenizedBuffer ?= new TokenizedBuffer({
tabLength, buffer, ignoreInvisibles, @largeFileMode, @config
tabLength, buffer, ignoreInvisibles, @largeFileMode, @config, @grammarRegistry
})
@buffer = @tokenizedBuffer.buffer
@charWidthsByScope = {}
@@ -103,7 +109,7 @@ class DisplayBuffer extends Model
copy: ->
newDisplayBuffer = new DisplayBuffer({
@buffer, tabLength: @getTabLength(), @largeFileMode, @config, @assert
@buffer, tabLength: @getTabLength(), @largeFileMode, @config, @assert, @grammarRegistry
})
for marker in @findMarkers(displayBufferId: @id)

View File

@@ -78,6 +78,7 @@ class TextEditor extends Model
state.notificationManager = atomEnvironment.notifications
state.clipboard = atomEnvironment.clipboard
state.viewRegistry = atomEnvironment.views
state.grammarRegistry = atomEnvironment.grammars
state.project = atomEnvironment.project
state.assert = atomEnvironment.assert.bind(atomEnvironment)
new this(state)
@@ -89,13 +90,14 @@ class TextEditor extends Model
@softTabs, @scrollRow, @scrollColumn, initialLine, initialColumn, tabLength,
softWrapped, @displayBuffer, buffer, suppressCursorCreation, @mini, @placeholderText,
lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @clipboard,
@viewRegistry, @project, @assert
@viewRegistry, @grammarRegistry, @project, @assert
} = params
throw new Error("Must pass a config parameter when constructing TextEditors") unless @config?
throw new Error("Must pass a notificationManager parameter when constructing TextEditors") unless @notificationManager?
throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard?
throw new Error("Must pass a viewRegistry parameter when constructing TextEditors") unless @viewRegistry?
throw new Error("Must pass a grammarRegistry parameter when constructing TextEditors") unless @grammarRegistry?
throw new Error("Must pass a project parameter when constructing TextEditors") unless @project?
throw new Error("Must pass an assert parameter when constructing TextEditors") unless @assert?
@@ -107,7 +109,7 @@ class TextEditor extends Model
buffer ?= new TextBuffer
@displayBuffer ?= new DisplayBuffer({
buffer, tabLength, softWrapped, ignoreInvisibles: @mini, largeFileMode,
@config, @assert
@config, @assert, @grammarRegistry
})
@buffer = @displayBuffer.buffer
@@ -475,7 +477,8 @@ class TextEditor extends Model
softTabs = @getSoftTabs()
newEditor = new TextEditor({
@buffer, displayBuffer, @tabLength, softTabs, suppressCursorCreation: true,
@config, @notificationManager, @clipboard, @viewRegistry, @project, @assert
@config, @notificationManager, @clipboard, @viewRegistry, @grammarRegistry,
@project, @assert
})
for marker in @findMarkers(editorId: @id)
marker.copy(editorId: newEditor.id, preserveFolds: true)

View File

@@ -24,15 +24,20 @@ class TokenizedBuffer extends Model
@deserialize: (state, atomEnvironment) ->
state.buffer = atom.project.bufferForPathSync(state.bufferPath)
state.config = atomEnvironment.config
state.grammarRegistry = atomEnvironment.grammars
new this(state)
constructor: ({@buffer, @tabLength, @ignoreInvisibles, @largeFileMode, @config}) ->
constructor: (params) ->
{
@buffer, @tabLength, @ignoreInvisibles, @largeFileMode, @config, @grammarRegistry
} = params
@emitter = new Emitter
@disposables = new CompositeDisposable
@tokenIterator = new TokenIterator
@disposables.add atom.grammars.onDidAddGrammar(@grammarAddedOrUpdated)
@disposables.add atom.grammars.onDidUpdateGrammar(@grammarAddedOrUpdated)
@disposables.add @grammarRegistry.onDidAddGrammar(@grammarAddedOrUpdated)
@disposables.add @grammarRegistry.onDidUpdateGrammar(@grammarAddedOrUpdated)
@disposables.add @buffer.preemptDidChange (e) => @handleBufferChange(e)
@disposables.add @buffer.onDidChangePath (@bufferPath) => @reloadGrammar()
@@ -66,7 +71,7 @@ class TokenizedBuffer extends Model
if grammar.injectionSelector?
@retokenizeLines() if @hasTokenForSelector(grammar.injectionSelector)
else
newScore = atom.grammars.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent())
newScore = @grammarRegistry.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent())
@setGrammar(grammar, newScore) if newScore > @currentGrammarScore
setGrammar: (grammar, score) ->
@@ -74,7 +79,7 @@ class TokenizedBuffer extends Model
@grammar = grammar
@rootScopeDescriptor = new ScopeDescriptor(scopes: [@grammar.scopeName])
@currentGrammarScore = score ? atom.grammars.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent())
@currentGrammarScore = score ? @grammarRegistry.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent())
@grammarUpdateDisposable?.dispose()
@grammarUpdateDisposable = @grammar.onDidUpdate => @retokenizeLines()
@@ -108,7 +113,7 @@ class TokenizedBuffer extends Model
@buffer.getTextInRange([[0, 0], [10, 0]])
reloadGrammar: ->
if grammar = atom.grammars.selectGrammar(@buffer.getPath(), @getGrammarSelectionContent())
if grammar = @grammarRegistry.selectGrammar(@buffer.getPath(), @getGrammarSelectionContent())
@setGrammar(grammar)
else
throw new Error("No grammar found for path: #{path}")
@@ -156,7 +161,7 @@ class TokenizedBuffer extends Model
tokenizeNextChunk: ->
# Short circuit null grammar which can just use the placeholder tokens
if @grammar is atom.grammars.nullGrammar and @firstInvalidRow()?
if @grammar is @grammarRegistry.nullGrammar and @firstInvalidRow()?
@invalidRows = []
@markTokenizationComplete()
return
@@ -473,13 +478,13 @@ class TokenizedBuffer extends Model
position = Point.fromObject(position)
{openScopes, tags} = @tokenizedLineForRow(position.row)
scopes = openScopes.map (tag) -> atom.grammars.scopeForId(tag)
scopes = openScopes.map (tag) => @grammarRegistry.scopeForId(tag)
startColumn = 0
for tag, tokenIndex in tags
if tag < 0
if tag % 2 is -1
scopes.push(atom.grammars.scopeForId(tag))
scopes.push(@grammarRegistry.scopeForId(tag))
else
scopes.pop()
else
@@ -499,7 +504,7 @@ class TokenizedBuffer extends Model
if tag % 2 is -1
startScopes.pop()
else
startScopes.push(atom.grammars.scopeForId(tag))
startScopes.push(@grammarRegistry.scopeForId(tag))
else
break unless selectorMatchesAnyScope(selector, startScopes)
startColumn -= tag
@@ -509,7 +514,7 @@ class TokenizedBuffer extends Model
tag = tags[endTokenIndex]
if tag < 0
if tag % 2 is -1
endScopes.push(atom.grammars.scopeForId(tag))
endScopes.push(@grammarRegistry.scopeForId(tag))
else
endScopes.pop()
else

View File

@@ -28,7 +28,8 @@ class Workspace extends Model
{
@packageManager, @config, @project, @grammarRegistry, @notificationManager,
@clipboard, @viewRegistry, @setRepresentedFilename, @setDocumentEdited, @assert
@clipboard, @viewRegistry, @grammarRegistry, @setRepresentedFilename,
@setDocumentEdited, @assert
} = params
debugger unless @assert?
@@ -460,7 +461,11 @@ class Workspace extends Model
@buildTextEditor(_.extend({buffer, largeFileMode}, options))
buildTextEditor: (params) ->
new TextEditor(_.extend({@config, @notificationManager, @clipboard, @viewRegistry, @project, @assert}, params))
params = _.extend({
@config, @notificationManager, @clipboard, @viewRegistry, @grammarRegistry,
@project, @assert
}, params)
new TextEditor(params)
# Public: Asynchronously reopens the last-closed item's URI if it hasn't already been
# reopened.