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 {