mirror of
https://github.com/atom/atom.git
synced 2026-02-09 14:15:24 -05:00
WIP: Reworking auto-indent/outdent logic
This commit is contained in:
@@ -329,17 +329,27 @@ class Buffer
|
||||
isRowBlank: (row) ->
|
||||
not /\S/.test @lineForRow(row)
|
||||
|
||||
nextNonBlankRow: (row) ->
|
||||
lastRow = @getLastRow()
|
||||
if row < lastRow
|
||||
for row in [(row + 1)..lastRow]
|
||||
return row unless @isRowBlank(row)
|
||||
previousNonBlankRow: (startRow) ->
|
||||
startRow = Math.min(startRow, @getLastRow())
|
||||
for row in [(startRow - 1)..0]
|
||||
return row unless @isRowBlank(row)
|
||||
null
|
||||
|
||||
nextNonBlankRow: (startRow) ->
|
||||
lastRow = @getLastRow()
|
||||
if startRow < lastRow
|
||||
for row in [(startRow + 1)..lastRow]
|
||||
return row unless @isRowBlank(row)
|
||||
null
|
||||
|
||||
indentationForRow: (row) ->
|
||||
@lineForRow(row).match(/^\s*/)?[0].length
|
||||
|
||||
setIndentationForRow: (bufferRow, newLevel) ->
|
||||
currentLevel = @indentationForRow(bufferRow)
|
||||
indentString = [0...newLevel].map(-> ' ').join('')
|
||||
@change([[bufferRow, 0], [bufferRow, currentLevel]], indentString)
|
||||
|
||||
logLines: (start=0, end=@getLastRow())->
|
||||
for row in [start..end]
|
||||
line = @lineForRow(row)
|
||||
|
||||
@@ -247,17 +247,17 @@ class EditSession
|
||||
largestFoldStartingAtScreenRow: (screenRow) ->
|
||||
@displayBuffer.largestFoldStartingAtScreenRow(screenRow)
|
||||
|
||||
indentationForRow: (row) ->
|
||||
@languageMode.indentationForRow(row)
|
||||
autoIndentBufferRows: (startRow, endRow) ->
|
||||
@languageMode.autoIndentBufferRows(startRow, endRow)
|
||||
|
||||
autoIndentRows: (startRow, endRow) ->
|
||||
@autoIndentRow(row) for row in [startRow..endRow]
|
||||
autoIndentBufferRow: (bufferRow) ->
|
||||
@languageMode.autoIndentBufferRow(bufferRow)
|
||||
|
||||
autoIndentRow: (row) ->
|
||||
actualIndentation = @lineForBufferRow(row).match(/^\s*/)[0]
|
||||
desiredIndentation = @indentationForRow(row)
|
||||
if actualIndentation != desiredIndentation
|
||||
@buffer.change([[row, 0], [row, actualIndentation.length]], desiredIndentation)
|
||||
autoIncreaseIndentForBufferRow: (bufferRow) ->
|
||||
@languageMode.autoIncreaseIndentForBufferRow(bufferRow)
|
||||
|
||||
autoDecreaseIndentForRow: (bufferRow) ->
|
||||
@languageMode.autoDecreaseIndentForBufferRow(bufferRow)
|
||||
|
||||
toggleLineCommentsInRange: (range) ->
|
||||
@languageMode.toggleLineCommentsInRange(range)
|
||||
|
||||
@@ -13,7 +13,8 @@ class LanguageMode
|
||||
"'": "'"
|
||||
|
||||
constructor: (@editSession) ->
|
||||
@grammar = TextMateBundle.grammarForFileName(@editSession.buffer.getBaseName())
|
||||
@buffer = @editSession.buffer
|
||||
@grammar = TextMateBundle.grammarForFileName(@buffer.getBaseName())
|
||||
|
||||
_.adviseBefore @editSession, 'insertText', (text) =>
|
||||
return true if @editSession.hasMultipleCursors()
|
||||
@@ -84,25 +85,43 @@ class LanguageMode
|
||||
|
||||
[bufferRow, foldEndRow]
|
||||
|
||||
indentationForRow: (row) ->
|
||||
for precedingRow in [row - 1..-1]
|
||||
return if precedingRow < 0
|
||||
precedingLine = @editSession.buffer.lineForRow(precedingRow)
|
||||
break if /\S/.test(precedingLine)
|
||||
|
||||
autoIndentBufferRows: (startRow, endRow) ->
|
||||
@autoIndentBufferRow(row) for row in [startRow..endRow]
|
||||
|
||||
autoIndentBufferRow: (bufferRow) ->
|
||||
@autoIncreaseIndentForBufferRow(bufferRow)
|
||||
@autoDecreaseIndentForBufferRow(bufferRow)
|
||||
|
||||
autoIncreaseIndentForBufferRow: (bufferRow) ->
|
||||
precedingRow = @buffer.previousNonBlankRow(bufferRow)
|
||||
return unless precedingRow?
|
||||
|
||||
precedingLine = @editSession.lineForBufferRow(precedingRow)
|
||||
scopes = @tokenizedBuffer.scopesForPosition([precedingRow, Infinity])
|
||||
indentation = precedingLine.match(/^\s*/)[0]
|
||||
increaseIndentPattern = TextMateBundle.getPreferenceInScope(scopes[0], 'increaseIndentPattern')
|
||||
decreaseIndentPattern = TextMateBundle.getPreferenceInScope(scopes[0], 'decreaseIndentPattern')
|
||||
increaseIndentPattern = new OnigRegExp(TextMateBundle.getPreferenceInScope(scopes[0], 'increaseIndentPattern'))
|
||||
|
||||
if new OnigRegExp(increaseIndentPattern).search(precedingLine)
|
||||
indentation += @editSession.tabText
|
||||
currentIndentation = @buffer.indentationForRow(bufferRow)
|
||||
desiredIndentation = @buffer.indentationForRow(precedingRow)
|
||||
desiredIndentation += @editSession.tabText.length if increaseIndentPattern.test(precedingLine)
|
||||
if desiredIndentation > currentIndentation
|
||||
@buffer.setIndentationForRow(bufferRow, desiredIndentation)
|
||||
|
||||
line = @editSession.buffer.lineForRow(row)
|
||||
if new OnigRegExp(decreaseIndentPattern).search(line)
|
||||
indentation = indentation.replace(@editSession.tabText, "")
|
||||
autoDecreaseIndentForBufferRow: (bufferRow) ->
|
||||
scopes = @tokenizedBuffer.scopesForPosition([bufferRow, 0])
|
||||
increaseIndentPattern = new OnigRegExp(TextMateBundle.getPreferenceInScope(scopes[0], 'increaseIndentPattern'))
|
||||
decreaseIndentPattern = new OnigRegExp(TextMateBundle.getPreferenceInScope(scopes[0], 'decreaseIndentPattern'))
|
||||
line = @buffer.lineForRow(bufferRow)
|
||||
return unless decreaseIndentPattern.test(line)
|
||||
|
||||
indentation
|
||||
currentIndentation = @buffer.indentationForRow(bufferRow)
|
||||
precedingRow = @buffer.previousNonBlankRow(bufferRow)
|
||||
precedingLine = @buffer.lineForRow(precedingRow)
|
||||
|
||||
desiredIndentation = @buffer.indentationForRow(precedingRow)
|
||||
desiredIndentation -= @editSession.tabText.length unless increaseIndentPattern.test(precedingLine)
|
||||
if desiredIndentation < currentIndentation
|
||||
@buffer.setIndentationForRow(bufferRow, desiredIndentation)
|
||||
|
||||
getLineTokens: (line, stack) ->
|
||||
{tokens, stack} = @grammar.getLineTokens(line, stack)
|
||||
|
||||
@@ -74,3 +74,6 @@ class Range
|
||||
else
|
||||
columns = @end.column
|
||||
new Point(rows, columns)
|
||||
|
||||
getRowCount: ->
|
||||
@end.row - @start.row + 1
|
||||
|
||||
@@ -134,7 +134,18 @@ class Selection
|
||||
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
|
||||
|
||||
if @editSession.autoIndent
|
||||
@editSession.autoIndentRows(newBufferRange.start.row, newBufferRange.end.row)
|
||||
if /\n/.test(text)
|
||||
firstLinePrefix = @editSession.getTextInBufferRange([[newBufferRange.start.row, 0], newBufferRange.start])
|
||||
if /^\s*$/.test(firstLinePrefix)
|
||||
@editSession.autoIncreaseIndentForBufferRow(newBufferRange.start.row)
|
||||
if newBufferRange.getRowCount() > 1
|
||||
@editSession.autoIndentBufferRows(newBufferRange.start.row + 1, newBufferRange.end.row)
|
||||
else
|
||||
@editSession.autoIncreaseIndentForBufferRow(newBufferRange.start.row + 1)
|
||||
if newBufferRange.getRowCount() > 2
|
||||
@editSession.autoIndentBufferRows(newBufferRange.start.row + 2, newBufferRange.end.row)
|
||||
else
|
||||
@editSession.autoDecreaseIndentForRow(newBufferRange.start.row)
|
||||
|
||||
backspace: ->
|
||||
if @isEmpty() and not @editSession.isFoldedAtScreenRow(@cursor.getScreenRow())
|
||||
|
||||
Reference in New Issue
Block a user