Improve auto indenting by removing a hard coded restriction and adding a 3rd regexp

Currently there are only two regexps that can influence the indents.
Those are `increaseIndentPattern` (which tells Atom the indent of next
line should be increased) and `decreaseIndentPattern` (which tells Atom
the indent of the current line should be decreased).

But I found that a couple of languages would need a 3rd regexp in order
to support their use cases. This 3rd regexp should be a mixture of the
existing two so it tells Atom that the indent of the next line should
decrease.

I’ll add a screencast to show a use case for this 3rd regexp which I
would like to call `decreaseNextIndentPattern`.
This commit is contained in:
Sander van Harmelen
2015-05-15 13:08:40 +02:00
committed by Sander van Harmelen
parent 1ebc8db123
commit eaf814e5be
4 changed files with 78 additions and 21 deletions

View File

@@ -127,7 +127,7 @@
"language-css": "0.32.0",
"language-gfm": "0.78.0",
"language-git": "0.10.0",
"language-go": "0.27.0",
"language-go": "0.28.0",
"language-html": "0.40.0",
"language-hyperlink": "0.14.0",
"language-java": "0.15.0",

View File

@@ -2226,12 +2226,56 @@ describe "TextEditor", ->
expect(editor.lineTextForBufferRow(1)).toBe ' '
expect(editor.lineTextForBufferRow(2)).toBe '}'
describe "when a new line is appended before a closing tag (e.g. by pressing enter before a selection)", ->
it "moves the line down and keeps the indentation level the same when editor.autoIndent is true", ->
atom.config.set('editor.autoIndent', true)
editor.setCursorBufferPosition([9, 2])
editor.insertNewline()
expect(editor.lineTextForBufferRow(10)).toBe ' };'
describe ".insertNewLine()", ->
describe "when a new line is appended before a closing tag (e.g. by pressing enter before a selection)", ->
it "moves the line down and keeps the indentation level the same when editor.autoIndent is true", ->
atom.config.set('editor.autoIndent', true)
editor.setCursorBufferPosition([9, 2])
editor.insertNewline()
expect(editor.lineTextForBufferRow(10)).toBe ' };'
describe "when a newline is appended with a trailing closing tag behind the cursor (e.g. by pressing enter in the middel of a line)", ->
it "indents the new line to the correct level when editor.autoIndent is true and using a curly-bracket language", ->
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
runs ->
atom.config.set("editor.autoIndent", true)
editor.setGrammar(atom.grammars.selectGrammar("file.js"))
editor.setText('var test = function () {\n return true;};')
editor.setCursorBufferPosition([1, 14])
editor.insertNewline()
expect(editor.indentationForBufferRow(1)).toBe 1
expect(editor.indentationForBufferRow(2)).toBe 0
it "indents the new line to the correct level when editor.autoIndent is true and using a off-side rule language", ->
waitsForPromise ->
atom.packages.activatePackage('language-coffee-script')
runs ->
atom.config.set("editor.autoIndent", true)
editor.setGrammar(atom.grammars.selectGrammar("file.coffee"))
editor.setText('if true\n return trueelse\n return false')
editor.setCursorBufferPosition([1, 13])
editor.insertNewline()
expect(editor.indentationForBufferRow(1)).toBe 1
expect(editor.indentationForBufferRow(2)).toBe 0
expect(editor.indentationForBufferRow(3)).toBe 1
describe "when a newline is appended on a line that matches the decreaseNextIndentRegex", ->
it "indents the new line to the correct level when editor.autoIndent is true", ->
waitsForPromise ->
atom.packages.activatePackage('language-go')
runs ->
atom.config.set("editor.autoIndent", true)
editor.setGrammar(atom.grammars.selectGrammar("file.go"))
editor.setText('fmt.Printf("some%s",\n "thing")')
editor.setCursorBufferPosition([1, 10])
editor.insertNewline()
expect(editor.indentationForBufferRow(1)).toBe 1
expect(editor.indentationForBufferRow(2)).toBe 0
describe ".backspace()", ->
describe "when there is a single cursor", ->

View File

@@ -246,8 +246,12 @@ class LanguageMode
iterator.next()
scopeDescriptor = new ScopeDescriptor(scopes: iterator.getScopes())
increaseIndentRegex = @increaseIndentRegexForScopeDescriptor(scopeDescriptor)
decreaseIndentRegex = @decreaseIndentRegexForScopeDescriptor(scopeDescriptor)
decreaseNextIndentRegex = @decreaseNextIndentRegexForScopeDescriptor(scopeDescriptor)
currentIndentLevel = @editor.indentationForBufferRow(bufferRow)
return currentIndentLevel unless increaseIndentRegex = @increaseIndentRegexForScopeDescriptor(scopeDescriptor)
return currentIndentLevel unless increaseIndentRegex
if options?.skipBlankLines ? true
precedingRow = @buffer.previousNonBlankRow(bufferRow)
@@ -256,13 +260,17 @@ class LanguageMode
precedingRow = bufferRow - 1
return currentIndentLevel if precedingRow < 0
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel = @editor.indentationForBufferRow(precedingRow)
desiredIndentLevel += 1 if increaseIndentRegex.testSync(precedingLine) and not @editor.isBufferRowCommented(precedingRow)
return desiredIndentLevel if @buffer.isRowBlank(precedingRow)
return desiredIndentLevel unless decreaseIndentRegex = @decreaseIndentRegexForScopeDescriptor(scopeDescriptor)
line = @buffer.lineForRow(bufferRow)
desiredIndentLevel -= 1 if decreaseIndentRegex.testSync(line)
unless @editor.isBufferRowCommented(precedingRow)
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel += 1 if increaseIndentRegex?.testSync(precedingLine)
desiredIndentLevel -= 1 if decreaseNextIndentRegex?.testSync(precedingLine)
unless @editor.isBufferRowCommented(bufferRow)
bufferLine = @buffer.lineForRow(bufferRow)
desiredIndentLevel -= 1 if decreaseIndentRegex?.testSync(bufferLine)
Math.max(desiredIndentLevel, 0)
@@ -298,21 +306,26 @@ class LanguageMode
# bufferRow - The row {Number}
autoDecreaseIndentForBufferRow: (bufferRow) ->
scopeDescriptor = @editor.scopeDescriptorForBufferPosition([bufferRow, 0])
increaseIndentRegex = @increaseIndentRegexForScopeDescriptor(scopeDescriptor)
decreaseIndentRegex = @decreaseIndentRegexForScopeDescriptor(scopeDescriptor)
return unless increaseIndentRegex and decreaseIndentRegex
return unless decreaseIndentRegex = @decreaseIndentRegexForScopeDescriptor(scopeDescriptor)
line = @buffer.lineForRow(bufferRow)
return unless decreaseIndentRegex.testSync(line)
currentIndentLevel = @editor.indentationForBufferRow(bufferRow)
return if currentIndentLevel is 0
precedingRow = @buffer.previousNonBlankRow(bufferRow)
return unless precedingRow?
precedingLine = @buffer.lineForRow(precedingRow)
precedingLine = @buffer.lineForRow(precedingRow)
desiredIndentLevel = @editor.indentationForBufferRow(precedingRow)
desiredIndentLevel -= 1 unless increaseIndentRegex.testSync(precedingLine)
if increaseIndentRegex = @increaseIndentRegexForScopeDescriptor(scopeDescriptor)
desiredIndentLevel -= 1 unless increaseIndentRegex.testSync(precedingLine)
if decreaseNextIndentRegex = @decreaseNextIndentRegexForScopeDescriptor(scopeDescriptor)
desiredIndentLevel -= 1 if decreaseNextIndentRegex.testSync(precedingLine)
if desiredIndentLevel >= 0 and desiredIndentLevel < currentIndentLevel
@editor.setIndentationForBufferRow(bufferRow, desiredIndentLevel)
@@ -326,6 +339,9 @@ class LanguageMode
decreaseIndentRegexForScopeDescriptor: (scopeDescriptor) ->
@getRegexForProperty(scopeDescriptor, 'editor.decreaseIndentPattern')
decreaseNextIndentRegexForScopeDescriptor: (scopeDescriptor) ->
@getRegexForProperty(scopeDescriptor, 'editor.decreaseNextIndentPattern')
foldEndRegexForScopeDescriptor: (scopeDescriptor) ->
@getRegexForProperty(scopeDescriptor, 'editor.foldEndPattern')

View File

@@ -395,10 +395,7 @@ class Selection extends Model
@editor.setIndentationForBufferRow(oldBufferRange.start.row, desiredIndentLevel)
if options.autoIndentNewline and text is '\n'
currentIndentation = @editor.indentationForBufferRow(newBufferRange.start.row)
@editor.autoIndentBufferRow(newBufferRange.end.row, preserveLeadingWhitespace: true, skipBlankLines: false)
if @editor.indentationForBufferRow(newBufferRange.end.row) < currentIndentation
@editor.setIndentationForBufferRow(newBufferRange.end.row, currentIndentation)
else if options.autoDecreaseIndent and NonWhitespaceRegExp.test(text)
@editor.autoDecreaseIndentForBufferRow(newBufferRange.start.row)