Look before and after empty lines for max indent level

Previously the indentation guide level for empty lines was
derived by only looking after the empty line which caused gaps
in certain cases.

Now the indentation for an empty line is the higher value of the
previous non-empty line indentation and the following non-empty
line indentation.

Closes #588
This commit is contained in:
Kevin Sawicki
2013-06-18 09:52:11 -07:00
parent aa9577db67
commit 1178d844d0
2 changed files with 72 additions and 20 deletions

View File

@@ -1565,6 +1565,20 @@ 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 indentation level on a line after an empty line is changed", ->
it "updates the indent guide on the empty line", ->
editor.attachToDom()
config.set("editor.showIndentGuide", true)
expect(editor.renderedLines.find('.line:eq(10) .indent-guide').length).toBe 1
expect(editor.renderedLines.find('.line:eq(10) .indent-guide').text()).toBe ' '
editor.setCursorBufferPosition([11])
editor.indentSelectedRows()
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 a line contains only whitespace", ->
it "displays an indent guide on the line", ->
editor.attachToDom()
@@ -1577,6 +1591,16 @@ 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 ' '
it "uses the highest indent guide level from the next or previous non-empty line", ->
editor.attachToDom()
config.set("editor.showIndentGuide", true)
editor.setCursorBufferPosition([1, Infinity])
editor.insertNewline()
expect(editor.getCursorBufferPosition()).toEqual [2, 0]
expect(editor.renderedLines.find('.line:eq(2) .indent-guide').length).toBe 2
expect(editor.renderedLines.find('.line:eq(2) .indent-guide').text()).toBe ' '
describe "when the line has leading and trailing whitespace", ->
it "does not display the indent guide in the trailing whitespace", ->
editor.attachToDom()
@@ -1587,7 +1611,7 @@ describe "Editor", ->
expect(editor.renderedLines.find('.line:eq(1) .indent-guide')).toHaveClass('leading-whitespace')
describe "when the line is empty and end of show invisibles are enabled", ->
it "renders the indent guides interleaved the end of line invisibles", ->
it "renders the indent guides interleaved with the end of line invisibles", ->
editor.attachToDom()
config.set("editor.showIndentGuide", true)
config.set("editor.showInvisibles", true)

View File

@@ -1185,21 +1185,34 @@ class Editor extends View
@updateLayerDimensions()
@updatePaddingOfRenderedLines()
computeSurroundingEmptyLineChanges: (change) ->
emptyLineChanges = []
if change.bufferDelta?
afterStart = change.end + change.bufferDelta + 1
if @lineForBufferRow(afterStart) is ''
afterEnd = afterStart
afterEnd++ while @lineForBufferRow(afterEnd + 1) is ''
emptyLineChanges.push({start: afterStart, end: afterEnd, screenDelta: 0})
beforeEnd = change.start - 1
if @lineForBufferRow(beforeEnd) is ''
beforeStart = beforeEnd
beforeStart-- while @lineForBufferRow(beforeStart - 1) is ''
emptyLineChanges.push({start: beforeStart, end: beforeEnd, screenDelta: 0})
emptyLineChanges
computeIntactRanges: ->
return [] if !@firstRenderedScreenRow? and !@lastRenderedScreenRow?
intactRanges = [{start: @firstRenderedScreenRow, end: @lastRenderedScreenRow, domStart: 0}]
if not @mini and @showIndentGuide
trailingEmptyLineChanges = []
emptyLineChanges = []
for change in @pendingChanges
continue unless change.bufferDelta?
start = change.end + change.bufferDelta + 1
continue unless @lineForBufferRow(start) is ''
end = start
end++ while @lineForBufferRow(end + 1) is ''
trailingEmptyLineChanges.push({start, end, screenDelta: 0})
@pendingChanges.push(trailingEmptyLineChanges...)
emptyLineChanges.push(@computeSurroundingEmptyLineChanges(change)...)
@pendingChanges.push(emptyLineChanges...)
for change in @pendingChanges
newIntactRanges = []
@@ -1355,15 +1368,31 @@ class Editor extends View
Editor.buildLineHtml({tokens, text, lineEnding, fold, isSoftWrapped, invisibles, eolInvisibles, htmlEolInvisibles, attributes, @showIndentGuide, indentation, @activeEditSession, @mini})
@buildIndentation: (screenRow, activeEditSession) ->
indentation = 0
while --screenRow >= 0
bufferRow = activeEditSession.bufferPositionForScreenPosition([screenRow]).row
bufferLine = activeEditSession.lineForBufferRow(bufferRow)
unless bufferLine is ''
indentation = Math.ceil(activeEditSession.indentLevelForLine(bufferLine))
break
bufferRow = activeEditSession.bufferPositionForScreenPosition([screenRow]).row
bufferLine = activeEditSession.lineForBufferRow(bufferRow)
if bufferLine is ''
indentation = 0
nextRow = screenRow + 1
while nextRow < activeEditSession.getBuffer().getLineCount()
bufferRow = activeEditSession.bufferPositionForScreenPosition([nextRow]).row
bufferLine = activeEditSession.lineForBufferRow(bufferRow)
if bufferLine isnt ''
indentation = Math.ceil(activeEditSession.indentLevelForLine(bufferLine))
break
nextRow++
indentation
previousRow = screenRow - 1
while previousRow >= 0
bufferRow = activeEditSession.bufferPositionForScreenPosition([previousRow]).row
bufferLine = activeEditSession.lineForBufferRow(bufferRow)
if bufferLine isnt ''
indentation = Math.max(indentation, Math.ceil(activeEditSession.indentLevelForLine(bufferLine)))
break
previousRow--
indentation
else
Math.ceil(activeEditSession.indentLevelForLine(bufferLine))
buildHtmlEndOfLineInvisibles: (screenLine) ->
invisibles = []
@@ -1571,9 +1600,8 @@ class Editor extends View
return indentGuideHtml.join('')
invisibles = htmlEolInvisibles
if invisibles.length > 0
invisibles
if htmlEolInvisibles.length > 0
htmlEolInvisibles
else
'&nbsp;'