mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Indent works with hard tabs
This commit is contained in:
@@ -671,7 +671,7 @@ describe "EditSession", ->
|
||||
it "auto-indents the new line to one additional level of indentation beyond the preceding line", ->
|
||||
editSession.setCursorBufferPosition([1, Infinity])
|
||||
editSession.insertText('\n', autoIndent: true)
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 2
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 1
|
||||
|
||||
describe "when the newline is inserted on a normal line", ->
|
||||
it "auto-indents the new line to the same level of indentation as the preceding line", ->
|
||||
@@ -686,7 +686,7 @@ describe "EditSession", ->
|
||||
editSession.setCursorBufferPosition([2, 4])
|
||||
editSession.insertText('\n', autoIndent: true)
|
||||
editSession.setCursorBufferPosition([2, 4])
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 2
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 1
|
||||
editSession.insertText(' }', autoIndent: true)
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1)
|
||||
|
||||
@@ -696,14 +696,14 @@ describe "EditSession", ->
|
||||
editSession.insertText('\n', autoIndent: true)
|
||||
expect(editSession.indentationForBufferRow(4)).toBe editSession.indentationForBufferRow(3)
|
||||
editSession.insertText(' }', autoIndent: true)
|
||||
expect(editSession.indentationForBufferRow(4)).toBe editSession.indentationForBufferRow(3) - 2
|
||||
expect(editSession.indentationForBufferRow(4)).toBe editSession.indentationForBufferRow(3) - 1
|
||||
|
||||
describe "when the current line does not match an auto-outdent pattern", ->
|
||||
it "leaves the line unchanged", ->
|
||||
editSession.setCursorBufferPosition([2, 4])
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 2
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 1
|
||||
editSession.insertText('foo', autoIndent: true)
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 2
|
||||
expect(editSession.indentationForBufferRow(2)).toBe editSession.indentationForBufferRow(1) + 1
|
||||
|
||||
describe "when the `normalizeIndent` option is true", ->
|
||||
describe "when the inserted text contains no newlines", ->
|
||||
@@ -746,7 +746,7 @@ describe "EditSession", ->
|
||||
it "indents all lines relative to the suggested indent", ->
|
||||
editSession.insertText('\n xx')
|
||||
editSession.setCursorBufferPosition([3, 1])
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent: true, indentBasis: 4)
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent: true, indentBasis: 2)
|
||||
|
||||
expect(editSession.lineForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editSession.lineForBufferRow(4)).toBe " foo();"
|
||||
@@ -767,7 +767,7 @@ describe "EditSession", ->
|
||||
describe "when an indentBasis is provided", ->
|
||||
it "preserves the current indent level, indenting all lines relative to it", ->
|
||||
editSession.insertText('\n ')
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent: true, indentBasis: 4)
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent: true, indentBasis: 2)
|
||||
|
||||
expect(editSession.lineForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editSession.lineForBufferRow(4)).toBe " foo();"
|
||||
@@ -791,7 +791,7 @@ describe "EditSession", ->
|
||||
describe "when an indentBasis is provided", ->
|
||||
it "always normalizes indented lines to the cursor's current indentation level", ->
|
||||
editSession.insertText('\n ')
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent: true, indentBasis: 4)
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent: true, indentBasis: 2)
|
||||
|
||||
expect(editSession.lineForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editSession.lineForBufferRow(4)).toBe " foo();"
|
||||
@@ -813,7 +813,7 @@ describe "EditSession", ->
|
||||
it "normalizes the indentation level of all lines based on the level of the existing first line", ->
|
||||
editSession.setAutoIndent(true)
|
||||
editSession.buffer.delete([[2, 0], [2, 2]])
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent:true, indentBasis: 4)
|
||||
editSession.insertText(removeLeadingWhitespace(text), normalizeIndent:true, indentBasis: 2)
|
||||
|
||||
expect(editSession.lineForBufferRow(2)).toBe " if (items.length <= 1) return items;while (true) {"
|
||||
expect(editSession.lineForBufferRow(3)).toBe " foo();"
|
||||
@@ -1214,6 +1214,9 @@ describe "EditSession", ->
|
||||
expect(buffer.lineForRow(1)).toBe ' var sort = function(it) {'
|
||||
|
||||
describe ".indent()", ->
|
||||
convertToHardTabs = ->
|
||||
buffer.setText(buffer.getText().replace(/[ ]{2}/g, "\t"))
|
||||
|
||||
describe "when the selection is empty", ->
|
||||
describe "when autoIndent is disabled", ->
|
||||
describe "if 'softTabs' is true (the default)", ->
|
||||
@@ -1223,7 +1226,37 @@ describe "EditSession", ->
|
||||
editSession.indent()
|
||||
expect(buffer.lineForRow(0)).toMatch(tabRegex)
|
||||
|
||||
describe "if 'softTabs' is false", ->
|
||||
it "insert a \t into the buffer", ->
|
||||
editSession.softTabs = false
|
||||
expect(buffer.lineForRow(0)).not.toMatch(/^\t/)
|
||||
editSession.indent()
|
||||
expect(buffer.lineForRow(0)).toMatch(/^\t/)
|
||||
|
||||
describe "when autoIndent is enabled", ->
|
||||
describe "when the cursor's column is less than the suggested level of indentation", ->
|
||||
describe "when 'softTabs' is true (the default)", ->
|
||||
it "inserts enough whitespace to bring the line to the suggested level of indentaion", ->
|
||||
buffer.insert([5, 0], " \n")
|
||||
editSession.tabLength = 2
|
||||
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 'softTabs' is false", ->
|
||||
it "inserts enough tabs to bring the line to the suggested level of indentaion", ->
|
||||
convertToHardTabs()
|
||||
editSession.softTabs = false
|
||||
buffer.insert([5, 0], "\t\n")
|
||||
editSession.setCursorBufferPosition [5, 1]
|
||||
editSession.setAutoIndent(true)
|
||||
editSession.indent()
|
||||
expect(buffer.lineForRow(5)).toMatch /^\t\t\t$/
|
||||
expect(editSession.getCursorBufferPosition()).toEqual [5, 3]
|
||||
|
||||
describe "when the cursor's column is greater than the suggested level of indentation", ->
|
||||
describe "when 'softTabs' is true (the default)", ->
|
||||
it "inserts 'tabLength' spaces into the buffer", ->
|
||||
@@ -1236,17 +1269,16 @@ describe "EditSession", ->
|
||||
expect(buffer.lineForRow(7).length).toBe 8
|
||||
expect(editSession.getCursorBufferPosition()).toEqual [7, 8]
|
||||
|
||||
describe "when the cursor's column is less than the suggested level of indentation", ->
|
||||
describe "when 'softTabs' is true (the default)", ->
|
||||
it "inserts enough whitespace to bring the line to the suggested level of indentaion", ->
|
||||
buffer.insert([5, 0], " \n")
|
||||
editSession.tabLength = 2
|
||||
editSession.setCursorBufferPosition [5, 2]
|
||||
describe "when 'softTabs' is false", ->
|
||||
it "inserts \t into the buffer", ->
|
||||
convertToHardTabs()
|
||||
editSession.softTabs = false
|
||||
buffer.insert([7, 0], "\t\t\t\n")
|
||||
editSession.setCursorBufferPosition [7, 3]
|
||||
editSession.setAutoIndent(true)
|
||||
editSession.indent()
|
||||
expect(buffer.lineForRow(5)).toMatch /^\s+$/
|
||||
expect(buffer.lineForRow(5).length).toBe 6
|
||||
expect(editSession.getCursorBufferPosition()).toEqual [5, 6]
|
||||
expect(buffer.lineForRow(7)).toMatch /^\t\t\t\t$/
|
||||
expect(editSession.getCursorBufferPosition()).toEqual [7, 4]
|
||||
|
||||
describe "when the selection is not empty", ->
|
||||
it "indents the selected lines", ->
|
||||
|
||||
@@ -183,9 +183,9 @@ describe "LanguageMode", ->
|
||||
describe "suggestedIndentForBufferRow", ->
|
||||
it "returns the suggested indentation based on auto-indent/outdent rules", ->
|
||||
expect(languageMode.suggestedIndentForBufferRow(0)).toBe 0
|
||||
expect(languageMode.suggestedIndentForBufferRow(1)).toBe 2
|
||||
expect(languageMode.suggestedIndentForBufferRow(2)).toBe 4
|
||||
expect(languageMode.suggestedIndentForBufferRow(9)).toBe 2
|
||||
expect(languageMode.suggestedIndentForBufferRow(1)).toBe 1
|
||||
expect(languageMode.suggestedIndentForBufferRow(2)).toBe 2
|
||||
expect(languageMode.suggestedIndentForBufferRow(9)).toBe 1
|
||||
|
||||
|
||||
describe "coffeescript", ->
|
||||
|
||||
@@ -162,6 +162,12 @@ class Cursor
|
||||
isAtBeginningOfLine: ->
|
||||
@getBufferPosition().column == 0
|
||||
|
||||
getIndentLevel: ->
|
||||
if @editSession.softTabs
|
||||
@getBufferColumn() / @editSession.tabLength
|
||||
else
|
||||
@getBufferColumn()
|
||||
|
||||
isAtEndOfLine: ->
|
||||
@getBufferPosition().isEqual(@getCurrentLineBufferRange().end)
|
||||
|
||||
|
||||
@@ -114,12 +114,25 @@ class EditSession
|
||||
@buffer.clipPosition(bufferPosition)
|
||||
|
||||
indentationForBufferRow: (bufferRow) ->
|
||||
@lineForBufferRow(bufferRow).match(/^\s*/)?[0].length
|
||||
@indentLevelForLine(@lineForBufferRow(bufferRow))
|
||||
|
||||
setIndentationForBufferRow: (bufferRow, newLevel) ->
|
||||
currentLevel = @indentationForBufferRow(bufferRow)
|
||||
indentString = [0...newLevel].map(-> ' ').join('')
|
||||
@buffer.change([[bufferRow, 0], [bufferRow, currentLevel]], indentString)
|
||||
currentIndentString = @buildIndentString(currentLevel)
|
||||
newIndentString = @buildIndentString(newLevel)
|
||||
@buffer.change([[bufferRow, 0], [bufferRow, currentIndentString.length]], newIndentString)
|
||||
|
||||
indentLevelForLine: (line) ->
|
||||
if @softTabs
|
||||
line.match(/^\s*/)?[0].length / @tabLength
|
||||
else
|
||||
line.match(/^\t*/)?[0].length
|
||||
|
||||
buildIndentString: (number) ->
|
||||
if @softTabs
|
||||
_.multiplyString(" ", number * @tabLength)
|
||||
else
|
||||
_.multiplyString("\t", number)
|
||||
|
||||
getFileExtension: -> @buffer.getExtension()
|
||||
getPath: -> @buffer.getPath()
|
||||
|
||||
@@ -83,13 +83,13 @@ class LanguageMode
|
||||
rowRangeForFoldAtBufferRow: (bufferRow) ->
|
||||
return null unless @doesBufferRowStartFold(bufferRow)
|
||||
|
||||
startIndentation = @editSession.indentationForBufferRow(bufferRow)
|
||||
startIndentLevel = @editSession.indentationForBufferRow(bufferRow)
|
||||
scopes = @tokenizedBuffer.scopesForPosition([bufferRow, 0])
|
||||
for row in [(bufferRow + 1)..@editSession.getLastBufferRow()]
|
||||
continue if @editSession.isBufferRowBlank(row)
|
||||
indentation = @editSession.indentationForBufferRow(row)
|
||||
if indentation <= startIndentation
|
||||
includeRowInFold = indentation == startIndentation and TextMateBundle.foldEndRegexForScope(@grammar, scopes[0]).search(@editSession.lineForBufferRow(row))
|
||||
if indentation <= startIndentLevel
|
||||
includeRowInFold = indentation == startIndentLevel and TextMateBundle.foldEndRegexForScope(@grammar, scopes[0]).search(@editSession.lineForBufferRow(row))
|
||||
foldEndRow = row if includeRowInFold
|
||||
break
|
||||
|
||||
@@ -98,23 +98,23 @@ class LanguageMode
|
||||
[bufferRow, foldEndRow]
|
||||
|
||||
suggestedIndentForBufferRow: (bufferRow) ->
|
||||
currentIndentation = @editSession.indentationForBufferRow(bufferRow)
|
||||
currentIndentLevel = @editSession.indentationForBufferRow(bufferRow)
|
||||
scopes = @tokenizedBuffer.scopesForPosition([bufferRow, 0])
|
||||
return currentIndentation unless increaseIndentPattern = TextMateBundle.indentRegexForScope(scopes[0])
|
||||
return currentIndentLevel unless increaseIndentPattern = TextMateBundle.indentRegexForScope(scopes[0])
|
||||
|
||||
currentLine = @buffer.lineForRow(bufferRow)
|
||||
precedingRow = @buffer.previousNonBlankRow(bufferRow)
|
||||
return currentIndentation unless precedingRow?
|
||||
return currentIndentLevel unless precedingRow?
|
||||
|
||||
precedingLine = @buffer.lineForRow(precedingRow)
|
||||
|
||||
desiredIndentation = @editSession.indentationForBufferRow(precedingRow)
|
||||
desiredIndentation += @editSession.tabLength if increaseIndentPattern.test(precedingLine)
|
||||
desiredIndentLevel = @editSession.indentationForBufferRow(precedingRow)
|
||||
desiredIndentLevel += 1 if increaseIndentPattern.test(precedingLine)
|
||||
|
||||
return desiredIndentation unless decreaseIndentPattern = TextMateBundle.outdentRegexForScope(scopes[0])
|
||||
desiredIndentation -= @editSession.tabLength if decreaseIndentPattern.test(currentLine)
|
||||
return desiredIndentLevel unless decreaseIndentPattern = TextMateBundle.outdentRegexForScope(scopes[0])
|
||||
desiredIndentLevel -= 1 if decreaseIndentPattern.test(currentLine)
|
||||
|
||||
Math.max(desiredIndentation, currentIndentation)
|
||||
Math.max(desiredIndentLevel, currentIndentLevel)
|
||||
|
||||
autoIndentBufferRows: (startRow, endRow) ->
|
||||
@autoIndentBufferRow(row) for row in [startRow..endRow]
|
||||
@@ -132,11 +132,11 @@ class LanguageMode
|
||||
increaseIndentPattern = TextMateBundle.indentRegexForScope(scopes[0])
|
||||
return unless increaseIndentPattern
|
||||
|
||||
currentIndentation = @editSession.indentationForBufferRow(bufferRow)
|
||||
desiredIndentation = @editSession.indentationForBufferRow(precedingRow)
|
||||
desiredIndentation += @editSession.tabLength if increaseIndentPattern.test(precedingLine)
|
||||
if desiredIndentation > currentIndentation
|
||||
@editSession.setIndentationForBufferRow(bufferRow, desiredIndentation)
|
||||
currentIndentLevel = @editSession.indentationForBufferRow(bufferRow)
|
||||
desiredIndentLevel = @editSession.indentationForBufferRow(precedingRow)
|
||||
desiredIndentLevel += 1 if increaseIndentPattern.test(precedingLine)
|
||||
if desiredIndentLevel > currentIndentLevel
|
||||
@editSession.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
|
||||
|
||||
autoDecreaseIndentForBufferRow: (bufferRow) ->
|
||||
scopes = @tokenizedBuffer.scopesForPosition([bufferRow, 0])
|
||||
@@ -147,14 +147,14 @@ class LanguageMode
|
||||
line = @buffer.lineForRow(bufferRow)
|
||||
return unless decreaseIndentPattern.test(line)
|
||||
|
||||
currentIndentation = @editSession.indentationForBufferRow(bufferRow)
|
||||
currentIndentLevel = @editSession.indentationForBufferRow(bufferRow)
|
||||
precedingRow = @buffer.previousNonBlankRow(bufferRow)
|
||||
precedingLine = @buffer.lineForRow(precedingRow)
|
||||
|
||||
desiredIndentation = @editSession.indentationForBufferRow(precedingRow)
|
||||
desiredIndentation -= @editSession.tabLength unless increaseIndentPattern.test(precedingLine)
|
||||
if desiredIndentation < currentIndentation
|
||||
@editSession.setIndentationForBufferRow(bufferRow, desiredIndentation)
|
||||
desiredIndentLevel = @editSession.indentationForBufferRow(precedingRow)
|
||||
desiredIndentLevel -= 1 unless increaseIndentPattern.test(precedingLine)
|
||||
if desiredIndentLevel < currentIndentLevel
|
||||
@editSession.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
|
||||
|
||||
getLineTokens: (line, stack) ->
|
||||
{tokens, stack} = @grammar.getLineTokens(line, stack)
|
||||
|
||||
@@ -153,9 +153,10 @@ class Selection
|
||||
|
||||
if @isEmpty()
|
||||
desiredIndent = @editSession.suggestedIndentForBufferRow(row)
|
||||
delta = desiredIndent - column
|
||||
delta = desiredIndent - @cursor.getIndentLevel()
|
||||
|
||||
if @editSession.autoIndent and delta > 0
|
||||
@insertText(new Array(delta + 1).join(' '))
|
||||
@insertText(@editSession.buildIndentString(delta))
|
||||
else
|
||||
if @editSession.softTabs
|
||||
@insertText(@editSession.getTabText())
|
||||
@@ -170,7 +171,7 @@ class Selection
|
||||
currentBufferRow = @cursor.getBufferRow()
|
||||
currentBufferColumn = @cursor.getBufferColumn()
|
||||
lines = text.split('\n')
|
||||
currentBasis = options.indentBasis ? lines[0].match(/\s*/)[0].length
|
||||
currentBasis = options.indentBasis ? @editSession.indentLevelForLine(lines[0])
|
||||
lines[0] = lines[0].replace(/^\s*/, '') # strip leading space from first line
|
||||
|
||||
normalizedLines = []
|
||||
@@ -183,14 +184,14 @@ class Selection
|
||||
else if @editSession.autoIndent
|
||||
desiredBasis = @editSession.suggestedIndentForBufferRow(currentBufferRow)
|
||||
else
|
||||
desiredBasis = currentBufferColumn
|
||||
desiredBasis = @cursor.getIndentLevel()
|
||||
|
||||
for line, i in lines
|
||||
if i == 0
|
||||
if insideExistingLine
|
||||
delta = 0
|
||||
else
|
||||
delta = desiredBasis - currentBufferColumn
|
||||
delta = desiredBasis - @cursor.getIndentLevel()
|
||||
else
|
||||
delta = desiredBasis - currentBasis
|
||||
|
||||
@@ -199,12 +200,12 @@ class Selection
|
||||
normalizedLines.join('\n')
|
||||
|
||||
adjustIndentationForLine: (line, delta) ->
|
||||
if delta > 0
|
||||
new Array(delta + 1).join(' ') + line
|
||||
else if delta < 0
|
||||
line.replace(new RegExp("^ {0,#{Math.abs(delta)}}"), '')
|
||||
else
|
||||
line
|
||||
currentIndentLevel = @editSession.indentLevelForLine(line)
|
||||
currentIndentString = @editSession.buildIndentString(currentIndentLevel)
|
||||
desiredIndentLevel = Math.max(0, currentIndentLevel + delta)
|
||||
desiredIndentString = @editSession.buildIndentString(desiredIndentLevel)
|
||||
|
||||
line.replace(new RegExp("^#{currentIndentString}"), desiredIndentString)
|
||||
|
||||
backspace: ->
|
||||
if @isEmpty() and not @editSession.isFoldedAtScreenRow(@cursor.getScreenRow())
|
||||
|
||||
@@ -68,4 +68,7 @@ _.mixin
|
||||
for key, value of hash
|
||||
inverted[value] ?= []
|
||||
inverted[value].push(key)
|
||||
inverted
|
||||
inverted
|
||||
|
||||
multiplyString: (string, n) ->
|
||||
new Array(1 + n).join(string)
|
||||
Reference in New Issue
Block a user