diff --git a/spec/app/display-buffer-spec.coffee b/spec/app/display-buffer-spec.coffee index 70faf4c21..a9a92cf71 100644 --- a/spec/app/display-buffer-spec.coffee +++ b/spec/app/display-buffer-spec.coffee @@ -2,16 +2,16 @@ DisplayBuffer = require 'display-buffer' Buffer = require 'buffer' describe "DisplayBuffer", -> - [displayBuffer, buffer, changeHandler, tabText] = [] + [editSession, displayBuffer, buffer, changeHandler, tabText] = [] beforeEach -> tabText = ' ' - buffer = new Buffer(require.resolve 'fixtures/sample.js') - displayBuffer = new DisplayBuffer(buffer, {tabText}) + editSession = fixturesProject.buildEditSessionForPath('sample.js', { tabText }) + { buffer, displayBuffer } = editSession changeHandler = jasmine.createSpy 'changeHandler' displayBuffer.on 'change', changeHandler afterEach -> - buffer.destroy() + editSession.destroy() describe "when the buffer changes", -> it "renders line numbers correctly", -> @@ -198,12 +198,16 @@ describe "DisplayBuffer", -> expect(fold.endRow).toBe 9 describe "primitive folding", -> + editSession2 = null + beforeEach -> - buffer.destroy() - buffer = new Buffer(require.resolve 'fixtures/two-hundred.txt') - displayBuffer = new DisplayBuffer(buffer, {tabText}) + editSession2 = fixturesProject.buildEditSessionForPath('two-hundred.txt') + { buffer, displayBuffer } = editSession2 displayBuffer.on 'change', changeHandler + afterEach -> + editSession2.destroy() + describe "when folds are created and destroyed", -> describe "when a fold spans multiple lines", -> it "replaces the lines spanned by the fold with a placeholder that references the fold object", -> diff --git a/spec/app/language-mode-spec.coffee b/spec/app/language-mode-spec.coffee new file mode 100644 index 000000000..68a2beaa0 --- /dev/null +++ b/spec/app/language-mode-spec.coffee @@ -0,0 +1,78 @@ +Project = require 'project' +Buffer = require 'buffer' +EditSession = require 'edit-session' + +describe "LanguageMode", -> + [editSession, buffer, languageMode] = [] + + afterEach -> + editSession.destroy() + + describe "javascript", -> + beforeEach -> + editSession = fixturesProject.buildEditSessionForPath('sample.js', autoIndent: false) + { buffer, languageMode } = editSession + + describe ".toggleLineCommentsInRange(range)", -> + it "comments/uncomments lines in the given range", -> + languageMode.toggleLineCommentsInRange([[4, 5], [7, 8]]) + expect(buffer.lineForRow(4)).toBe "// while(items.length > 0) {" + expect(buffer.lineForRow(5)).toBe "// current = items.shift();" + expect(buffer.lineForRow(6)).toBe "// current < pivot ? left.push(current) : right.push(current);" + expect(buffer.lineForRow(7)).toBe "// }" + + languageMode.toggleLineCommentsInRange([[4, 5], [5, 8]]) + expect(buffer.lineForRow(4)).toBe " while(items.length > 0) {" + expect(buffer.lineForRow(5)).toBe " current = items.shift();" + expect(buffer.lineForRow(6)).toBe "// current < pivot ? left.push(current) : right.push(current);" + expect(buffer.lineForRow(7)).toBe "// }" + + describe "fold suggestion", -> + describe ".isBufferRowFoldable(bufferRow)", -> + it "returns true only when the buffer row starts a foldable region", -> + expect(languageMode.isBufferRowFoldable(0)).toBeTruthy() + expect(languageMode.isBufferRowFoldable(1)).toBeTruthy() + expect(languageMode.isBufferRowFoldable(2)).toBeFalsy() + expect(languageMode.isBufferRowFoldable(3)).toBeFalsy() + + describe ".rowRangeForFoldAtBufferRow(bufferRow)", -> + it "returns the start/end rows of the foldable region starting at the given row", -> + expect(languageMode.rowRangeForFoldAtBufferRow(0)).toEqual [0, 12] + expect(languageMode.rowRangeForFoldAtBufferRow(1)).toEqual [1, 9] + expect(languageMode.rowRangeForFoldAtBufferRow(2)).toBeNull() + expect(languageMode.rowRangeForFoldAtBufferRow(4)).toEqual [4, 7] + + describe "coffeescript", -> + beforeEach -> + editSession = fixturesProject.buildEditSessionForPath('coffee.coffee', autoIndent: false) + { buffer, languageMode } = editSession + + describe ".toggleLineCommentsInRange(range)", -> + it "comments/uncomments lines in the given range", -> + languageMode.toggleLineCommentsInRange([[4, 5], [7, 8]]) + expect(buffer.lineForRow(4)).toBe " #pivot = items.shift()" + expect(buffer.lineForRow(5)).toBe " #left = []" + expect(buffer.lineForRow(6)).toBe " #right = []" + expect(buffer.lineForRow(7)).toBe "#" + + languageMode.toggleLineCommentsInRange([[4, 5], [5, 8]]) + expect(buffer.lineForRow(4)).toBe " pivot = items.shift()" + expect(buffer.lineForRow(5)).toBe " left = []" + expect(buffer.lineForRow(6)).toBe " #right = []" + expect(buffer.lineForRow(7)).toBe "#" + + describe "fold suggestion", -> + describe ".isBufferRowFoldable(bufferRow)", -> + it "returns true only when the buffer row starts a foldable region", -> + expect(languageMode.isBufferRowFoldable(0)).toBeTruthy() + expect(languageMode.isBufferRowFoldable(1)).toBeTruthy() + expect(languageMode.isBufferRowFoldable(2)).toBeFalsy() + expect(languageMode.isBufferRowFoldable(3)).toBeFalsy() + expect(languageMode.isBufferRowFoldable(19)).toBeTruthy() + + describe ".rowRangeForFoldAtBufferRow(bufferRow)", -> + it "returns the start/end rows of the foldable region starting at the given row", -> + expect(languageMode.rowRangeForFoldAtBufferRow(0)).toEqual [0, 20] + expect(languageMode.rowRangeForFoldAtBufferRow(1)).toEqual [1, 17] + expect(languageMode.rowRangeForFoldAtBufferRow(2)).toBeNull() + expect(languageMode.rowRangeForFoldAtBufferRow(19)).toEqual [19, 20] diff --git a/spec/app/line-map-spec.coffee b/spec/app/line-map-spec.coffee index 2891b92af..8aaf4347c 100644 --- a/spec/app/line-map-spec.coffee +++ b/spec/app/line-map-spec.coffee @@ -5,17 +5,17 @@ TokenizedBuffer = require 'tokenized-buffer' Point = require 'point' describe "LineMap", -> - [tokenizedBuffer, map] = [] + [editSession, tokenizedBuffer, map] = [] [line0, line1, line2, line3, line4] = [] beforeEach -> - buffer = new Buffer(require.resolve 'fixtures/sample.js') - tokenizedBuffer = new TokenizedBuffer(buffer) + editSession = fixturesProject.buildEditSessionForPath('sample.js') + { buffer, tokenizedBuffer } = editSession map = new LineMap [line0, line1, line2, line3, line4] = tokenizedBuffer.linesForScreenRows(0, 4) afterEach -> - tokenizedBuffer.buffer.destroy() + editSession.destroy() describe ".insertAtBufferRow(row, lineFragments)", -> it "inserts the given line fragments before the specified buffer row", -> diff --git a/spec/app/screen-line-spec.coffee b/spec/app/screen-line-spec.coffee index 86c5e795a..a3275866f 100644 --- a/spec/app/screen-line-spec.coffee +++ b/spec/app/screen-line-spec.coffee @@ -3,16 +3,16 @@ Buffer = require 'buffer' TokenizedBuffer = require 'tokenized-buffer' describe "ScreenLine", -> - [buffer, tabText, screenLine, tokenizedBuffer] = [] + [editSession, buffer, tabText, screenLine, tokenizedBuffer] = [] beforeEach -> tabText = ' ' - buffer = new Buffer(require.resolve 'fixtures/sample.js') - tokenizedBuffer = new TokenizedBuffer(buffer, tabText) + editSession = fixturesProject.buildEditSessionForPath('sample.js') + { buffer, tokenizedBuffer } = editSession screenLine = tokenizedBuffer.lineForScreenRow(3) afterEach -> - buffer.destroy() + editSession.destroy() describe ".splitAt(column)", -> it "breaks the line fragment into two fragments", -> diff --git a/spec/app/tokenized-buffer-spec.coffee b/spec/app/tokenized-buffer-spec.coffee index 7fb803825..ecdf2a128 100644 --- a/spec/app/tokenized-buffer-spec.coffee +++ b/spec/app/tokenized-buffer-spec.coffee @@ -1,16 +1,17 @@ TokenizedBuffer = require 'tokenized-buffer' +LanguageMode = require 'language-mode' Buffer = require 'buffer' Range = require 'range' describe "TokenizedBuffer", -> - [tokenizedBuffer, buffer] = [] + [editSession, tokenizedBuffer, buffer] = [] beforeEach -> - buffer = new Buffer(require.resolve('fixtures/sample.js')) - tokenizedBuffer = new TokenizedBuffer(buffer, ' ') + editSession = fixturesProject.buildEditSessionForPath('sample.js', autoIndent: false) + { tokenizedBuffer, buffer } = editSession afterEach -> - buffer.destroy() + editSession.destroy() describe ".findClosingBracket(startBufferPosition)", -> it "returns the position of the matching bracket, skipping any nested brackets", -> @@ -20,81 +21,6 @@ describe "TokenizedBuffer", -> it "returns the position of the matching bracket, skipping any nested brackets", -> expect(tokenizedBuffer.findOpeningBracket([9, 2])).toEqual [1, 29] - describe ".toggleLineCommentsInRange(range)", -> - describe "javascript", -> - it "comments/uncomments lines in the given range", -> - tokenizedBuffer.toggleLineCommentsInRange([[4, 5], [7, 8]]) - expect(buffer.lineForRow(4)).toBe "// while(items.length > 0) {" - expect(buffer.lineForRow(5)).toBe "// current = items.shift();" - expect(buffer.lineForRow(6)).toBe "// current < pivot ? left.push(current) : right.push(current);" - expect(buffer.lineForRow(7)).toBe "// }" - - tokenizedBuffer.toggleLineCommentsInRange([[4, 5], [5, 8]]) - expect(buffer.lineForRow(4)).toBe " while(items.length > 0) {" - expect(buffer.lineForRow(5)).toBe " current = items.shift();" - expect(buffer.lineForRow(6)).toBe "// current < pivot ? left.push(current) : right.push(current);" - expect(buffer.lineForRow(7)).toBe "// }" - - describe "coffeescript", -> - it "comments/uncomments lines in the given range", -> - buffer.destroy() - buffer = new Buffer(require.resolve('fixtures/coffee.coffee')) - tokenizedBuffer = new TokenizedBuffer(buffer, ' ') - - tokenizedBuffer.toggleLineCommentsInRange([[4, 5], [7, 8]]) - expect(buffer.lineForRow(4)).toBe " #pivot = items.shift()" - expect(buffer.lineForRow(5)).toBe " #left = []" - expect(buffer.lineForRow(6)).toBe " #right = []" - expect(buffer.lineForRow(7)).toBe "#" - - tokenizedBuffer.toggleLineCommentsInRange([[4, 5], [5, 8]]) - expect(buffer.lineForRow(4)).toBe " pivot = items.shift()" - expect(buffer.lineForRow(5)).toBe " left = []" - expect(buffer.lineForRow(6)).toBe " #right = []" - expect(buffer.lineForRow(7)).toBe "#" - - describe "fold suggestion", -> - describe "javascript", -> - beforeEach -> - buffer.destroy() - buffer = new Buffer(require.resolve 'fixtures/sample.js') - tokenizedBuffer = new TokenizedBuffer(buffer) - - describe ".isBufferRowFoldable(bufferRow)", -> - it "returns true only when the buffer row starts a foldable region", -> - expect(tokenizedBuffer.isBufferRowFoldable(0)).toBeTruthy() - expect(tokenizedBuffer.isBufferRowFoldable(1)).toBeTruthy() - expect(tokenizedBuffer.isBufferRowFoldable(2)).toBeFalsy() - expect(tokenizedBuffer.isBufferRowFoldable(3)).toBeFalsy() - - describe ".rowRangeForFoldAtBufferRow(bufferRow)", -> - it "returns the start/end rows of the foldable region starting at the given row", -> - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(0)).toEqual [0, 12] - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(1)).toEqual [1, 9] - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(2)).toBeNull() - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(4)).toEqual [4, 7] - - describe "coffeescript", -> - beforeEach -> - buffer.destroy() - buffer = new Buffer(require.resolve 'fixtures/coffee.coffee') - tokenizedBuffer = new TokenizedBuffer(buffer) - - describe ".isBufferRowFoldable(bufferRow)", -> - it "returns true only when the buffer row starts a foldable region", -> - expect(tokenizedBuffer.isBufferRowFoldable(0)).toBeTruthy() - expect(tokenizedBuffer.isBufferRowFoldable(1)).toBeTruthy() - expect(tokenizedBuffer.isBufferRowFoldable(2)).toBeFalsy() - expect(tokenizedBuffer.isBufferRowFoldable(3)).toBeFalsy() - expect(tokenizedBuffer.isBufferRowFoldable(19)).toBeTruthy() - - describe ".rowRangeForFoldAtBufferRow(bufferRow)", -> - it "returns the start/end rows of the foldable region starting at the given row", -> - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(0)).toEqual [0, 20] - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(1)).toEqual [1, 17] - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(2)).toBeNull() - expect(tokenizedBuffer.rowRangeForFoldAtBufferRow(19)).toEqual [19, 20] - describe "tokenization", -> it "tokenizes all the lines in the buffer on construction", -> expect(tokenizedBuffer.lineForScreenRow(0).tokens[0]).toEqual(type: 'keyword.definition', value: 'var') @@ -225,13 +151,15 @@ describe "TokenizedBuffer", -> expect(event.newRange).toEqual new Range([2, 0], [7, buffer.lineForRow(7).length]) describe "when the buffer contains tab characters", -> - tabText = null + tabText = ' ' + editSession2 = null beforeEach -> - tabText = ' ' - buffer.destroy() - buffer = new Buffer(require.resolve('fixtures/sample-with-tabs.coffee')) - tokenizedBuffer = new TokenizedBuffer(buffer, tabText) + editSession2 = fixturesProject.buildEditSessionForPath('sample-with-tabs.coffee', { tabText }) + { buffer, tokenizedBuffer } = editSession2 + + afterEach -> + editSession2.destroy() it "always renders each tab as its own atomic token containing tabText", -> screenLine0 = tokenizedBuffer.lineForScreenRow(0) diff --git a/src/app/ace-adaptor.coffee b/src/app/ace-adaptor.coffee index 200cead62..8869db8aa 100644 --- a/src/app/ace-adaptor.coffee +++ b/src/app/ace-adaptor.coffee @@ -4,8 +4,8 @@ module.exports = class AceAdaptor foldWidgets: {} - constructor: (@tokenizedBuffer) -> - @buffer = @tokenizedBuffer.buffer + constructor: (@editSession) -> + @buffer = @editSession.buffer getLine: (bufferRow) -> @buffer.lineForRow(bufferRow) @@ -14,7 +14,7 @@ class AceAdaptor @buffer.getLineCount() $findClosingBracket: (bracketType, bufferPosition) -> - @tokenizedBuffer.findClosingBracket([bufferPosition.row, bufferPosition.column - 1]) + @editSession.tokenizedBuffer.findClosingBracket([bufferPosition.row, bufferPosition.column - 1]) indentRows: (startRow, endRow, indentString) -> for row in [startRow..endRow] @@ -25,4 +25,4 @@ class AceAdaptor @buffer.change(range, text) findMatchingBracket: ({row, column}) -> - @tokenizedBuffer.findOpeningBracket([row, column]) + @editSession.tokenizedBuffer.findOpeningBracket([row, column]) diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 2ea45661a..29035a32b 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -12,6 +12,7 @@ module.exports = class DisplayBuffer @idCounter: 1 lineMap: null + languageMode: null tokenizedBuffer: null activeFolds: null foldsById: null @@ -19,7 +20,9 @@ class DisplayBuffer constructor: (@buffer, options={}) -> @id = @constructor.idCounter++ - @tokenizedBuffer = new TokenizedBuffer(@buffer, options.tabText ? ' ') + options.tabText ?= ' ' + @languageMode = options.languageMode + @tokenizedBuffer = new TokenizedBuffer(@buffer, options) @softWrapColumn = options.softWrapColumn ? Infinity @activeFolds = {} @foldsById = {} @@ -51,14 +54,14 @@ class DisplayBuffer foldAll: -> for currentRow in [0..@buffer.getLastRow()] - [startRow, endRow] = @tokenizedBuffer.rowRangeForFoldAtBufferRow(currentRow) ? [] + [startRow, endRow] = @languageMode.rowRangeForFoldAtBufferRow(currentRow) ? [] continue unless startRow? @createFold(startRow, endRow) toggleFoldAtBufferRow: (bufferRow) -> for currentRow in [bufferRow..0] - [startRow, endRow] = @tokenizedBuffer.rowRangeForFoldAtBufferRow(currentRow) ? [] + [startRow, endRow] = @languageMode.rowRangeForFoldAtBufferRow(currentRow) ? [] continue unless startRow? and startRow <= bufferRow <= endRow if fold = @largestFoldStartingAtBufferRow(startRow) @@ -209,7 +212,7 @@ class DisplayBuffer startBufferColumn = 0 while currentBufferRow <= endBufferRow screenLine = @tokenizedBuffer.lineForScreenRow(currentBufferRow) - screenLine.foldable = @tokenizedBuffer.isBufferRowFoldable(currentBufferRow) + screenLine.foldable = @languageMode.isBufferRowFoldable(currentBufferRow) if fold = @largestFoldStartingAtBufferRow(currentBufferRow) screenLine = screenLine.copy() diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 90996f294..aeb2e24c6 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -1,6 +1,7 @@ Point = require 'point' Buffer = require 'buffer' Anchor = require 'anchor' +LanguageMode = require 'language-mode' DisplayBuffer = require 'display-buffer' Cursor = require 'cursor' Selection = require 'selection' @@ -22,6 +23,7 @@ class EditSession scrollTop: 0 scrollLeft: 0 + languageMode: null displayBuffer: null anchors: null anchorRanges: null @@ -34,7 +36,8 @@ class EditSession constructor: ({@project, @buffer, @tabText, @autoIndent, @softTabs, @softWrap}) -> @id = @constructor.idCounter++ @softTabs ?= true - @displayBuffer = new DisplayBuffer(@buffer, { @tabText }) + @languageMode = new LanguageMode(this, @buffer.getExtension()) + @displayBuffer = new DisplayBuffer(@buffer, { @languageMode, @tabText }) @tokenizedBuffer = @displayBuffer.tokenizedBuffer @anchors = [] @anchorRanges = [] @@ -242,17 +245,17 @@ class EditSession @displayBuffer.largestFoldStartingAtScreenRow(screenRow) indentationForRow: (row) -> - @tokenizedBuffer.indentationForRow(row) + @languageMode.indentationForRow(row) autoIndentTextAfterBufferPosition: (text, bufferPosition) -> return { text } unless @autoIndent - @tokenizedBuffer.autoIndentTextAfterBufferPosition(text, bufferPosition) + @languageMode.autoIndentTextAfterBufferPosition(text, bufferPosition) autoOutdentBufferRow: (bufferRow) -> - @tokenizedBuffer.autoOutdentBufferRow(bufferRow) + @languageMode.autoOutdentBufferRow(bufferRow) toggleLineCommentsInRange: (range) -> - @tokenizedBuffer.toggleLineCommentsInRange(range) + @languageMode.toggleLineCommentsInRange(range) mutateSelectedText: (fn) -> @transact => fn(selection) for selection in @getSelections() diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee new file mode 100644 index 000000000..077a0549f --- /dev/null +++ b/src/app/language-mode.coffee @@ -0,0 +1,60 @@ +AceAdaptor = require 'ace-adaptor' +Range = require 'range' + +module.exports = +class LanguageMode + constructor: (@editSession) -> + @buffer = @editSession.buffer + @aceMode = @requireAceMode() + @aceAdaptor = new AceAdaptor(@editSession) + + requireAceMode: (fileExtension) -> + modeName = switch @editSession.buffer.getExtension() + when 'js' then 'javascript' + when 'coffee' then 'coffee' + when 'rb', 'ru' then 'ruby' + when 'c', 'h', 'cpp' then 'c_cpp' + when 'html', 'htm' then 'html' + when 'css' then 'css' + when 'java' then 'java' + when 'xml' then 'xml' + else 'text' + new (require("ace/mode/#{modeName}").Mode) + + toggleLineCommentsInRange: (range) -> + range = Range.fromObject(range) + @aceMode.toggleCommentLines(@tokenizedBuffer.stateForRow(range.start.row), @aceAdaptor, range.start.row, range.end.row) + + isBufferRowFoldable: (bufferRow) -> + @aceMode.foldingRules?.getFoldWidget(@aceAdaptor, null, bufferRow) == "start" + + rowRangeForFoldAtBufferRow: (bufferRow) -> + if aceRange = @aceMode.foldingRules?.getFoldWidgetRange(@aceAdaptor, null, bufferRow) + [aceRange.start.row, aceRange.end.row] + else + null + + indentationForRow: (row) -> + state = @tokenizedBuffer.stateForRow(row) + previousRowText = @buffer.lineForRow(row - 1) + @aceMode.getNextLineIndent(state, previousRowText, @editSession.tabText) + + autoIndentTextAfterBufferPosition: (text, bufferPosition) -> + { row, column} = bufferPosition + state = @tokenizedBuffer.stateForRow(row) + lineBeforeCursor = @buffer.lineForRow(row)[0...column] + if text[0] == "\n" + indent = @aceMode.getNextLineIndent(state, lineBeforeCursor, @editSession.tabText) + text = text[0] + indent + text[1..] + else if @aceMode.checkOutdent(state, lineBeforeCursor, text) + shouldOutdent = true + + {text, shouldOutdent} + + autoOutdentBufferRow: (bufferRow) -> + state = @tokenizedBuffer.stateForRow(bufferRow) + @aceMode.autoOutdent(state, @aceAdaptor, bufferRow) + + getLineTokens: (line, state) -> + {tokens, state} = @aceMode.getTokenizer().getLineTokens(line, state) + diff --git a/src/app/tokenized-buffer.coffee b/src/app/tokenized-buffer.coffee index 15dc42a02..a028a6707 100644 --- a/src/app/tokenized-buffer.coffee +++ b/src/app/tokenized-buffer.coffee @@ -4,70 +4,21 @@ EventEmitter = require 'event-emitter' Token = require 'token' Range = require 'range' Point = require 'point' -AceAdaptor = require 'ace-adaptor' module.exports = class TokenizedBuffer @idCounter: 1 + languageMode: null buffer: null - aceMode: null aceAdaptor: null screenLines: null - constructor: (@buffer, @tabText) -> + constructor: (@buffer, { @languageMode, @tabText }) -> + @languageMode.tokenizedBuffer = this @id = @constructor.idCounter++ - @aceMode = @requireAceMode() @screenLines = @buildScreenLinesForRows('start', 0, @buffer.getLastRow()) @buffer.on "change.tokenized-buffer#{@id}", (e) => @handleBufferChange(e) - @aceAdaptor = new AceAdaptor(this) - - requireAceMode: -> - modeName = switch @buffer.getExtension() - when 'js' then 'javascript' - when 'coffee' then 'coffee' - when 'rb', 'ru' then 'ruby' - when 'c', 'h', 'cpp' then 'c_cpp' - when 'html', 'htm' then 'html' - when 'css' then 'css' - when 'java' then 'java' - when 'xml' then 'xml' - else 'text' - new (require("ace/mode/#{modeName}").Mode) - - toggleLineCommentsInRange: (range) -> - range = Range.fromObject(range) - @aceMode.toggleCommentLines(@stateForRow(range.start.row), @aceAdaptor, range.start.row, range.end.row) - - isBufferRowFoldable: (bufferRow) -> - @aceMode.foldingRules?.getFoldWidget(@aceAdaptor, null, bufferRow) == "start" - - rowRangeForFoldAtBufferRow: (bufferRow) -> - if aceRange = @aceMode.foldingRules?.getFoldWidgetRange(@aceAdaptor, null, bufferRow) - [aceRange.start.row, aceRange.end.row] - else - null - - indentationForRow: (row) -> - state = @stateForRow(row) - previousRowText = @buffer.lineForRow(row - 1) - @aceMode.getNextLineIndent(state, previousRowText, @tabText) - - autoIndentTextAfterBufferPosition: (text, bufferPosition) -> - { row, column} = bufferPosition - state = @stateForRow(row) - lineBeforeCursor = @buffer.lineForRow(row)[0...column] - if text[0] == "\n" - indent = @aceMode.getNextLineIndent(state, lineBeforeCursor, @tabText) - text = text[0] + indent + text[1..] - else if @aceMode.checkOutdent(state, lineBeforeCursor, text) - shouldOutdent = true - - {text, shouldOutdent} - - autoOutdentBufferRow: (bufferRow) -> - state = @stateForRow(bufferRow) - @aceMode.autoOutdent(state, @aceAdaptor, bufferRow) handleBufferChange: (e) -> oldRange = e.oldRange.copy() @@ -108,9 +59,8 @@ class TokenizedBuffer screenLine buildScreenLineForRow: (state, row) -> - tokenizer = @aceMode.getTokenizer() line = @buffer.lineForRow(row) - {tokens, state} = tokenizer.getLineTokens(line, state) + {tokens, state} = @languageMode.getLineTokens(line, state) tokenObjects = [] for tokenProperties in tokens token = new Token(tokenProperties)