From 905002cd5879ecf459c8fea7e71c03df94bb39ec Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Sat, 22 Dec 2012 22:02:29 -0800 Subject: [PATCH] Highlight foreground of selected line numbers Previously no gutter highlight was displayed unless the selection was empty. Now there is a separate CSS class for no selection that changes the background color independently from the foreground color. --- spec/app/editor-spec.coffee | 25 +++++++----- spec/stdlib/child-process-spec.coffee | 2 +- src/app/gutter.coffee | 56 +++++++++++++++++++-------- static/editor.css | 3 +- 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 693e3b93e..f7c99be4f 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -1728,14 +1728,14 @@ describe "Editor", -> describe "when there is no wrapping", -> it "highlights the line where the initial cursor position is", -> expect(editor.getCursorBufferPosition().row).toBe 0 - expect(editor.find('.line-number.cursor-line').length).toBe 1 - expect(editor.find('.line-number.cursor-line').text()).toBe "1" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "1" it "updates the highlighted line when the cursor position changes", -> editor.setCursorBufferPosition([1,0]) expect(editor.getCursorBufferPosition().row).toBe 1 - expect(editor.find('.line-number.cursor-line').length).toBe 1 - expect(editor.find('.line-number.cursor-line').text()).toBe "2" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "2" describe "when there is wrapping", -> beforeEach -> @@ -1745,23 +1745,28 @@ describe "Editor", -> it "highlights the line where the initial cursor position is", -> expect(editor.getCursorBufferPosition().row).toBe 0 - expect(editor.find('.line-number.cursor-line').length).toBe 1 - expect(editor.find('.line-number.cursor-line').text()).toBe "1" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "1" it "updates the highlighted line when the cursor position changes", -> editor.setCursorBufferPosition([1,0]) expect(editor.getCursorBufferPosition().row).toBe 1 - expect(editor.find('.line-number.cursor-line').length).toBe 1 - expect(editor.find('.line-number.cursor-line').text()).toBe "2" + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').length).toBe 1 + expect(editor.find('.line-number.cursor-line.cursor-line-no-selection').text()).toBe "2" describe "when the selection spans multiple lines", -> beforeEach -> editor.attachToDom(30) - it "doesn't highlight the background or the gutter", -> + it "highlights the foreground of the gutter", -> editor.getSelection().setBufferRange(new Range([0,0],[2,0])) expect(editor.getSelection().isSingleScreenLine()).toBe false - expect(editor.find('.line-number.cursor-line').length).toBe 0 + expect(editor.find('.line-number.cursor-line').length).toBe 3 + + it "doesn't highlight the background of the gutter", -> + editor.getSelection().setBufferRange(new Range([0,0],[2,0])) + expect(editor.getSelection().isSingleScreenLine()).toBe false + expect(editor.find('.line-number.cursor-line-no-selection').length).toBe 0 it "when a newline is deleted with backspace, the line number of the new cursor position is highlighted", -> editor.setCursorScreenPosition([1,0]) diff --git a/spec/stdlib/child-process-spec.coffee b/spec/stdlib/child-process-spec.coffee index 985d814b4..4c389f087 100644 --- a/spec/stdlib/child-process-spec.coffee +++ b/spec/stdlib/child-process-spec.coffee @@ -126,4 +126,4 @@ describe 'Child Processes', -> ChildProcess.exec(cmd, options) runs -> - expect(output.length).toBeGreaterThan 1 \ No newline at end of file + expect(output.length).toBeGreaterThan 1 diff --git a/src/app/gutter.coffee b/src/app/gutter.coffee index 4910e21ba..f6a8440aa 100644 --- a/src/app/gutter.coffee +++ b/src/app/gutter.coffee @@ -2,6 +2,7 @@ $ = require 'jquery' _ = require 'underscore' +Range = require 'range' module.exports = class Gutter extends View @@ -18,9 +19,9 @@ class Gutter extends View @attached = true editor = @editor() - highlightCursorLine = => @highlightCursorLine() - editor.on 'cursor-move', highlightCursorLine - editor.on 'selection-change', highlightCursorLine + highlightLines = => @highlightLines() + editor.on 'cursor-move', highlightLines + editor.on 'selection-change', highlightLines @calculateWidth() editor: -> @@ -63,8 +64,8 @@ class Gutter extends View @calculateWidth() @firstScreenRow = startScreenRow @lastScreenRow = endScreenRow - @highlightedRow = null - @highlightCursorLine() + @highlightedRows = null + @highlightLines() calculateWidth: -> highestNumberWidth = @editor().getLineCount().toString().length * @editor().charWidth @@ -73,17 +74,38 @@ class Gutter extends View @lineNumbers.width(highestNumberWidth + @calculateLineNumberPadding()) @widthChanged?(@outerWidth()) - highlightCursorLine: -> - if @editor().getSelection().isEmpty() - rowToHighlight = @editor().getCursorScreenPosition().row - return if rowToHighlight == @highlightedRow - return if rowToHighlight < @firstScreenRow or rowToHighlight > @lastScreenRow + removeLineHighlights: -> + return unless @highlightedLineNumbers + for line in @highlightedLineNumbers + line.classList.remove('cursor-line') + line.classList.remove('cursor-line-no-selection') + @highlightedLineNumbers = null - @highlightedLineNumber?.classList.remove('cursor-line') - if @highlightedLineNumber = @lineNumbers[0].children[rowToHighlight - @firstScreenRow] - @highlightedLineNumber.classList.add('cursor-line') - @highlightedRow = rowToHighlight + addLineHighlight: (row, emptySelection) -> + return if row < @firstScreenRow or row > @lastScreenRow + @highlightedLineNumbers ?= [] + if highlightedLineNumber = @lineNumbers[0].children[row - @firstScreenRow] + highlightedLineNumber.classList.add('cursor-line') + highlightedLineNumber.classList.add('cursor-line-no-selection') if emptySelection + @highlightedLineNumbers.push(highlightedLineNumber) + + highlightLines: -> + if @editor().getSelection().isEmpty() + row = @editor().getCursorScreenPosition().row + rowRange = new Range([row, 0], [row, 0]) + return if @highlightedRows?.isEqual(rowRange) and @selectionEmpty + + @removeLineHighlights() + @addLineHighlight(row, true) + @highlightedRows = rowRange + @selectionEmpty = true else - @highlightedLineNumber?.classList.remove('cursor-line') - @highlightedLineNumber = null - @highlightedRow = null + selectedRows = @editor().getSelection().getScreenRange() + selectedRows = new Range([selectedRows.start.row, 0], [selectedRows.end.row, 0]) + return if @highlightedRows?.isEqual(selectedRows) and not @selectionEmpty + + @removeLineHighlights() + for row in [selectedRows.start.row..selectedRows.end.row] + @addLineHighlight(row, false) + @highlightedRows = selectedRows + @selectionEmpty = false diff --git a/static/editor.css b/static/editor.css index 7c6e10db7..e1892bee1 100644 --- a/static/editor.css +++ b/static/editor.css @@ -33,7 +33,8 @@ color: rgba(255, 255, 255, .6); } -.editor.focused .cursor-line { +.editor.focused .line-number.cursor-line-no-selection, +.editor.focused .line.cursor-line { background-color: rgba(255, 255, 255, .12); }