diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 7419ef4ee..7a9f98d07 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -1551,6 +1551,22 @@ describe "Editor", -> expect(editor.renderedLines.find('.line:eq(10) .indent-guide').length).toBe 2 expect(editor.renderedLines.find('.line:eq(10) .indent-guide').text()).toBe ' ' + describe "when the line is empty and end of show invisibles are enabled", -> + it "renders the indent guides interleaved the end of line invisibles", -> + editor.attachToDom() + config.set("editor.showIndentGuide", true) + config.set("editor.showInvisibles", true) + eol = editor.invisibles?.eol + + expect(editor.renderedLines.find('.line:eq(10) .indent-guide').length).toBe 1 + expect(editor.renderedLines.find('.line:eq(10) .indent-guide').text()).toBe "#{eol} " + + editor.setCursorBufferPosition([9]) + editor.indent() + + expect(editor.renderedLines.find('.line:eq(10) .indent-guide').length).toBe 2 + expect(editor.renderedLines.find('.line:eq(10) .indent-guide').text()).toBe "#{eol} " + describe "when soft-wrap is enabled", -> beforeEach -> editor.attachToDom() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index abfdafc72..44037d13a 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -1546,7 +1546,22 @@ class Editor extends View htmlLines.push(@buildLineHtml(line, screenRow++)) htmlLines.join('\n\n') - buildEmptyLineHtml: (screenRow) -> + buildEndOfLineInvisibles: (screenLine) -> + invisibles = [] + for invisible in @getEndOfLineInvisibles(screenLine) + invisibles.push("#{invisible}") + invisibles.join('') + + getEndOfLineInvisibles: (screenLine) -> + return [] unless @showInvisibles and @invisibles + return [] if @mini or screenLine.isSoftWrapped() + + invisibles = [] + invisibles.push(@invisibles.cr) if @invisibles.cr and screenLine.lineEnding is '\r\n' + invisibles.push(@invisibles.eol) if @invisibles.eol + invisibles + + buildEmptyLineHtml: (screenLine, screenRow) -> if not @mini and @showIndentGuide indentation = 0 while --screenRow >= 0 @@ -1557,10 +1572,28 @@ class Editor extends View break if indentation > 0 - indentationHtml = "#{_.multiplyString(' ', @activeEditSession.getTabLength())}" - return _.multiplyString(indentationHtml, indentation) + tabLength = @activeEditSession.getTabLength() + invisibles = @getEndOfLineInvisibles(screenLine) + indentGuideHtml = [] + for level in [0...indentation] + indentLevelHtml = [""] + for characterPosition in [0...tabLength] + if invisible = invisibles.shift() + indentLevelHtml.push("#{invisible}") + else + indentLevelHtml.push(' ') + indentLevelHtml.push("") + indentGuideHtml.push(indentLevelHtml.join('')) - return ' ' unless @showInvisibles + for invisible in invisibles + indentGuideHtml.push("#{invisible}") + return indentGuideHtml.join('') + + invisibles = @buildEndOfLineInvisibles(screenLine) + if invisibles.length > 0 + invisibles + else + ' ' buildLineHtml: (screenLine, screenRow) -> scopeStack = [] @@ -1599,7 +1632,7 @@ class Editor extends View invisibles = @invisibles if @showInvisibles if screenLine.text == '' - html = @buildEmptyLineHtml(screenRow) + html = @buildEmptyLineHtml(screenLine, screenRow) line.push(html) if html else firstNonWhitespacePosition = screenLine.text.search(/\S/) @@ -1615,12 +1648,7 @@ class Editor extends View position += token.value.length popScope() while scopeStack.length > 0 - if invisibles and not @mini and not screenLine.isSoftWrapped() - if invisibles.cr and screenLine.lineEnding is '\r\n' - line.push("#{invisibles.cr}") - if invisibles.eol - line.push("#{invisibles.eol}") - + line.push(@buildEndOfLineInvisibles(screenLine)) unless screenLine.text == '' line.push("") if fold line.push('') diff --git a/static/editor.less b/static/editor.less index 699ffe3bc..cf3a4eb87 100644 --- a/static/editor.less +++ b/static/editor.less @@ -81,13 +81,11 @@ } .editor .invisible-character { - opacity: 0.2; font-weight: normal !important; font-style: normal !important; } .editor .indent-guide { - opacity: 0.2; display: inline-block; box-shadow: inset 1px 0px; } diff --git a/themes/atom-dark-syntax.css b/themes/atom-dark-syntax.css index e14796b22..a095d3018 100644 --- a/themes/atom-dark-syntax.css +++ b/themes/atom-dark-syntax.css @@ -3,6 +3,11 @@ color: #c5c8c6; } +.editor .invisible-character, +.editor .indent-guide { + color: rgba(197, 200, 198, .2); +} + .editor .gutter .line-number.fold, .editor .gutter .line-number:after, .editor .fold-marker:after { diff --git a/themes/atom-light-syntax.css b/themes/atom-light-syntax.css index 248630da8..774a3c561 100644 --- a/themes/atom-light-syntax.css +++ b/themes/atom-light-syntax.css @@ -3,6 +3,11 @@ color: #555; } +.editor .invisible-character, +.editor .indent-guide { + color: rgba(85, 85, 85, .2); +} + .editor .gutter .line-number.fold, .editor .gutter .line-number:after, .editor .fold-marker:after {