diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index f20184e01..64bb7adba 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -3707,11 +3707,12 @@ describe "TextEditor", -> expect(editor.indentLevelForLine("\t\thello")).toBe(2) it "returns the indent level based on the character starting the line when the leading whitespace contains both spaces and tabs", -> - expect(editor.indentLevelForLine("\t hello")).toBe(1) - expect(editor.indentLevelForLine(" \thello")).toBe(1) - expect(editor.indentLevelForLine(" \t hello")).toBe(1) - expect(editor.indentLevelForLine(" \t \thello")).toBe(2) - expect(editor.indentLevelForLine(" \t \thello")).toBe(2.5) + expect(editor.indentLevelForLine("\t hello")).toBe(2) + expect(editor.indentLevelForLine(" \thello")).toBe(2) + expect(editor.indentLevelForLine(" \t hello")).toBe(2.5) + expect(editor.indentLevelForLine(" \t \thello")).toBe(4) + expect(editor.indentLevelForLine(" \t \thello")).toBe(4) + expect(editor.indentLevelForLine(" \t \t hello")).toBe(4.5) describe "when the buffer is reloaded", -> it "preserves the current cursor position", -> diff --git a/src/selection.coffee b/src/selection.coffee index 3f7878195..6a4d4726f 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -622,7 +622,7 @@ class Selection extends Model else currentIndentLevel = @editor.indentLevelForLine(lines[i]) indentLevel = Math.max(0, currentIndentLevel + indentAdjustment) - lines[i] = line.replace(/^(\t+| +)/, @editor.buildIndentString(indentLevel)) + lines[i] = line.replace(/^[\t ]+/, @editor.buildIndentString(indentLevel)) return # Indent the current line(s). diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 3b19970b8..37d9c2021 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2447,13 +2447,14 @@ class TextEditor extends Model options.autoIndent ?= @shouldAutoIndent() @mutateSelectedText (selection) -> selection.indent(options) - # Constructs the string used for tabs. - buildIndentString: (number, column=0) -> + # Constructs the string used for indents. + buildIndentString: (level, column=0) -> if @getSoftTabs() tabStopViolation = column % @getTabLength() - _.multiplyString(" ", Math.floor(number * @getTabLength()) - tabStopViolation) + _.multiplyString(" ", Math.floor(level * @getTabLength()) - tabStopViolation) else - _.multiplyString("\t", Math.floor(number)) + excessWhitespace = _.multiplyString(' ', Math.round((level - Math.floor(level)) * @getTabLength())) + _.multiplyString("\t", Math.floor(level)) + excessWhitespace ### Section: Grammars diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 5919841f5..e44183489 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -421,10 +421,15 @@ class TokenizedBuffer extends Model @indentLevelForLine(line) indentLevelForLine: (line) -> - if match = line.match(/^\t+/) - match[0].length - else if match = line.match(/^ +/) - match[0].length / @getTabLength() + if match = line.match(/^[\t ]+/) + indentLength = 0 + for character in match[0] + if character is '\t' + indentLength += @getTabLength() - (indentLength % @getTabLength()) + else + indentLength++ + + indentLength / @getTabLength() else 0