From de5bd9105517c97966f00f0002ec8cf30c2d7319 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 6 Dec 2012 11:53:57 -0700 Subject: [PATCH] Paste indent normalization works with on lines w/ mixed indentation Normalizing the indent no longer explodes when pasting on a line that has mixed tabs and spaces when the edit session is using hard tabs. --- spec/app/edit-session-spec.coffee | 30 ++++++++++++++++++++++++++++++ src/app/edit-session.coffee | 9 ++++++--- src/app/selection.coffee | 4 +--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index dd0a6c3f1..4a60362a7 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -754,6 +754,22 @@ describe "EditSession", -> expect(editSession.lineForBufferRow(5)).toBe " }" expect(editSession.lineForBufferRow(6)).toBe " bar();xx" + describe "when inserting on a line that has mixed tabs and whitespace in hard tabs mode (regression)", -> + it "correctly indents the inserted text", -> + editSession.softTabs = false + buffer.setText """ + not indented + \tmixed indented + """ + + editSession.setCursorBufferPosition([1, 0]) + editSession.insertText(text, normalizeIndent: true) + + expect(editSession.lineForBufferRow(1)).toBe "\t\t\twhile (true) {" + expect(editSession.lineForBufferRow(2)).toBe "\t\t\t\tfoo();" + expect(editSession.lineForBufferRow(3)).toBe "\t\t\t}" + expect(editSession.lineForBufferRow(4)).toBe "\t\tbar(); \tmixed indented" + describe "when the cursor's current column is greater than the suggested indent level", -> describe "when the indentBasis is inferred from the first line", -> it "preserves the current indent level, indenting all lines relative to it", -> @@ -1776,3 +1792,17 @@ describe "EditSession", -> editSession = fixturesProject.buildEditSessionForPath(null, softTabs: false) expect(editSession.softTabs).toBeFalsy() + + describe ".indentLevelForLine(line)", -> + it "returns the indent level when the line has only leading whitespace", -> + expect(editSession.indentLevelForLine(" hello")).toBe(2) + expect(editSession.indentLevelForLine(" hello")).toBe(1.5) + + it "returns the indent level when the line has only leading tabs", -> + expect(editSession.indentLevelForLine("\t\thello")).toBe(2) + + it "returns the indent level when the line has mixed leading whitespace and tabs", -> + expect(editSession.indentLevelForLine("\t hello")).toBe(2) + expect(editSession.indentLevelForLine(" \thello")).toBe(2) + expect(editSession.indentLevelForLine(" \t hello")).toBe(2.5) + expect(editSession.indentLevelForLine(" \t \thello")).toBe(3.5) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 9ff5601a0..bcc0270fc 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -124,10 +124,13 @@ class EditSession @buffer.change([[bufferRow, 0], [bufferRow, currentIndentString.length]], newIndentString) indentLevelForLine: (line) -> - if line.match(/^\t/) - line.match(/^\t*/)?[0].length + if match = line.match(/^[\t ]+/) + leadingWhitespace = match[0] + tabCount = leadingWhitespace.match(/\t/g)?.length ? 0 + spaceCount = leadingWhitespace.match(/[ ]/g)?.length ? 0 + tabCount + (spaceCount / @getTabLength()) else - line.match(/^\s*/)?[0].length / @getTabLength() + 0 buildIndentString: (number) -> if @softTabs diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 7f19bf0bc..e091b887a 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -238,11 +238,9 @@ class Selection adjustIndentationForLine: (line, delta) -> currentIndentLevel = @editSession.indentLevelForLine(line) - currentIndentString = @editSession.buildIndentString(currentIndentLevel) desiredIndentLevel = Math.max(0, currentIndentLevel + delta) desiredIndentString = @editSession.buildIndentString(desiredIndentLevel) - - line.replace(new RegExp("^#{currentIndentString}"), desiredIndentString) + line.replace(/^[\t ]*/, desiredIndentString) backspace: -> if @isEmpty() and not @editSession.isFoldedAtScreenRow(@cursor.getScreenRow())