wip: IndentationForRow almost works TextMate preferences

This commit is contained in:
Corey Johnson 2012-08-02 16:26:40 -07:00
parent 82562c89dd
commit 08a55dfcac
6 changed files with 70 additions and 22 deletions

View File

@ -2,7 +2,7 @@ Project = require 'project'
Buffer = require 'buffer'
EditSession = require 'edit-session'
describe "EditSession", ->
fdescribe "EditSession", ->
[buffer, editSession, lineLengths] = []
beforeEach ->
@ -1106,6 +1106,28 @@ describe "EditSession", ->
expect(buffer.lineForRow(0)).toMatch(tabRegex)
describe "when auto-indent is on and there is no text after the cursor", ->
describe "when the preceding line opens a new level of indentation", ->
it "increases the level of indentation by one", ->
buffer.insert([5, 0], " \n")
editSession.tabText = " "
editSession.setCursorBufferPosition [5, 2]
editSession.setAutoIndent(true)
editSession.indent()
expect(buffer.lineForRow(5)).toMatch /^\s+$/
expect(buffer.lineForRow(5).length).toBe 6
expect(editSession.getCursorBufferPosition()).toEqual [5, 6]
describe "when there are empty lines preceding the current line", ->
it "bases indentation on the first non-blank preceding line", ->
buffer.insert([5, 0], "\n\n\n \n")
editSession.tabText = " "
editSession.setCursorBufferPosition [8, 2]
editSession.setAutoIndent(true)
editSession.indent()
expect(buffer.lineForRow(8)).toMatch /^\s+$/
expect(buffer.lineForRow(8).length).toBe 6
expect(editSession.getCursorBufferPosition()).toEqual [8, 6]
it "properly indents the line", ->
buffer.insert([7, 0], " \n")
editSession.tabText = " "

View File

@ -137,15 +137,11 @@ class EditSession
@insertNewline()
indent: ->
currentRow = @getCursorBufferPosition().row
if @getSelection().isEmpty()
whitespaceMatch = @lineForBufferRow(@getCursorBufferPosition().row).match /^\s*$/
whitespaceMatch = @lineForBufferRow(currentRow).match /^\s*$/
if @autoIndent and whitespaceMatch
indentation = @indentationForRow(@getCursorBufferPosition().row)
if indentation.length > whitespaceMatch[0].length
@getSelection().selectLine()
@insertText(indentation)
else
@insertText(@tabText)
@autoIndentRow(currentRow)
else if @softTabs
@insertText(@tabText)
else
@ -251,12 +247,14 @@ class EditSession
indentationForRow: (row) ->
@languageMode.indentationForRow(row)
autoIndentTextAfterBufferPosition: (text, bufferPosition) ->
return { text } unless @autoIndent
@languageMode.autoIndentTextAfterBufferPosition(text, bufferPosition)
autoIndentRows: (startRow, endRow) ->
@autoIndentRow(row) for row in [startRow..endRow]
autoOutdentBufferRow: (bufferRow) ->
@languageMode.autoOutdentBufferRow(bufferRow)
autoIndentRow: (row) ->
actualIndentation = @lineForBufferRow(row).match(/^\s*/)[0]
desiredIndentation = @indentationForRow(row)
if actualIndentation != desiredIndentation
@buffer.change([[row, 0], [row, actualIndentation.length]], desiredIndentation)
toggleLineCommentsInRange: (range) ->
@languageMode.toggleLineCommentsInRange(range)

View File

@ -73,21 +73,36 @@ class LanguageMode
null
indentationForRow: (row) ->
state = @tokenizedBuffer.stackForRow(row)
previousRowText = @buffer.lineForRow(row - 1)
@aceMode.getNextLineIndent(state, previousRowText, @editSession.tabText)
for precedingRow in [row - 1..-1]
return if precedingRow < 0
precedingLine = @editSession.buffer.lineForRow(precedingRow)
break if /\S/.test(precedingLine)
scopes = @tokenizedBuffer.scopesForPosition([precedingRow, Infinity])
indentation = precedingLine.match(/^\s*/)[0]
increaseIndentPattern = TextMateBundle.getPreferenceInScope(scopes[0], 'increaseIndentPattern')
decreaseIndentPattern = TextMateBundle.getPreferenceInScope(scopes[0], 'decreaseIndentPattern')
if new OnigRegExp(increaseIndentPattern).search(precedingLine)
indentation += @editSession.tabText
line = @editSession.buffer.lineForRow(row)
if new OnigRegExp(decreaseIndentPattern).search(line)
indentation = indentation.replace(@editSession.tabText, "")
indentation
autoIndentTextAfterBufferPosition: (text, bufferPosition) ->
{ row, column} = bufferPosition
state = @tokenizedBuffer.stackForRow(row)
stack = @tokenizedBuffer.stackForRow(row)
lineBeforeCursor = @buffer.lineForRow(row)[0...column]
if text[0] == "\n"
indent = @aceMode.getNextLineIndent(state, lineBeforeCursor, @editSession.tabText)
indent = @aceMode.getNextLineIndent(stack, lineBeforeCursor, @editSession.tabText)
text = text[0] + indent + text[1..]
else if @aceMode.checkOutdent(state, lineBeforeCursor, text)
else if @aceMode.checkOutdent(stack, lineBeforeCursor, text)
shouldOutdent = true
{text, shouldOutdent}
{text, shouldOutdent: false}
autoOutdentBufferRow: (bufferRow) ->
state = @tokenizedBuffer.stackForRow(bufferRow)

View File

@ -41,6 +41,13 @@ class ScreenLine
rightFragment = new ScreenLine(rightTokens, rightText, rightScreenDelta, rightBufferDelta, {@stack})
[leftFragment, rightFragment]
tokenAtBufferColumn: (bufferColumn) ->
delta = 0
for token in @tokens
delta += token.bufferDelta
return token if delta >= bufferColumn
token
concat: (other) ->
tokens = @tokens.concat(other.tokens)
text = @text + other.text

View File

@ -126,14 +126,15 @@ class Selection
@modifySelection => @cursor.moveToEndOfWord()
insertText: (text) ->
{ text, shouldOutdent } = @autoIndentText(text)
oldBufferRange = @getBufferRange()
@editSession.destroyFoldsContainingBufferRow(oldBufferRange.end.row)
wasReversed = @isReversed()
@clear()
newBufferRange = @editSession.buffer.change(oldBufferRange, text)
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
@autoOutdent() if shouldOutdent
if @editSession.autoIndent
@editSession.autoIndentRows(newBufferRange.start.row, newBufferRange.end.row)
backspace: ->
if @isEmpty() and not @editSession.isFoldedAtScreenRow(@cursor.getScreenRow())

View File

@ -77,6 +77,11 @@ class TokenizedBuffer
stackForRow: (row) ->
@screenLines[row]?.stack
scopesForPosition: (position) ->
position = Point.fromObject(position)
token = @screenLines[position.row].tokenAtBufferColumn(position.column)
token.scopes
destroy: ->
@buffer.off ".tokenized-buffer#{@id}"