Files
atom/src/app/gutter.coffee
Kevin Sawicki f868c0cd4f Add line diff decorations to editor gutter
Added, modified, and deleted lines will now highlighted
in the gutter for files already checked in to the repository.
2013-04-10 12:17:01 -07:00

127 lines
4.3 KiB
CoffeeScript

{View, $$, $$$} = require 'space-pen'
Range = require 'range'
$ = require 'jquery'
_ = require 'underscore'
module.exports =
class Gutter extends View
@content: ->
@div class: 'gutter', =>
@div outlet: 'lineNumbers', class: 'line-numbers'
firstScreenRow: Infinity
lastScreenRow: -1
highestNumberWidth: null
afterAttach: (onDom) ->
return if @attached or not onDom
@attached = true
highlightLines = => @highlightLines()
@getEditor().on 'cursor:moved', highlightLines
@getEditor().on 'selection:changed', highlightLines
@on 'mousedown', (e) => @handleMouseEvents(e)
getEditor: ->
@parentView
beforeRemove: ->
$(document).off(".gutter-#{@getEditor().id}")
handleMouseEvents: (e) ->
editor = @getEditor()
startRow = editor.screenPositionFromMouseEvent(e).row
if e.shiftKey
editor.selectToScreenPosition([startRow + 1, 0])
return
else
editor.getSelection().setScreenRange([[startRow, 0], [startRow, 0]])
moveHandler = (e) =>
start = startRow
end = editor.screenPositionFromMouseEvent(e).row
if end > start then end++ else start++
editor.getSelection().setScreenRange([[start, 0], [end, 0]])
$(document).on "mousemove.gutter-#{@getEditor().id}", moveHandler
$(document).one "mouseup.gutter-#{@getEditor().id}", => $(document).off 'mousemove', moveHandler
setShowLineNumbers: (showLineNumbers) ->
if showLineNumbers then @lineNumbers.show() else @lineNumbers.hide()
updateLineNumbers: (changes, renderFrom, renderTo) ->
if renderFrom < @firstScreenRow or renderTo > @lastScreenRow
performUpdate = true
else if @getEditor().getLastScreenRow() < @lastScreenRow
performUpdate = true
else
for change in changes
if change.delta != 0 or (change.bufferDelta? and change.bufferDelta != 0)
performUpdate = true
break
@renderLineNumbers(renderFrom, renderTo) if performUpdate
renderLineNumbers: (startScreenRow, endScreenRow) ->
editor = @getEditor()
maxDigits = editor.getLineCount().toString().length
rows = editor.bufferRowsForScreenRows(startScreenRow, endScreenRow)
cursorScreenRow = editor.getCursorScreenPosition().row
@lineNumbers[0].innerHTML = $$$ ->
for row in rows
if row == lastScreenRow
rowValue = ''
else
rowValue = (row + 1).toString()
classes = ['line-number']
classes.push('fold') if editor.isFoldedAtBufferRow(row)
@div lineNumber: row, class: classes.join(' '), =>
rowValuePadding = _.multiplyString('&nbsp;', maxDigits - rowValue.length)
@raw("#{rowValuePadding}#{rowValue}")
lastScreenRow = row
@firstScreenRow = startScreenRow
@lastScreenRow = endScreenRow
@highlightedRows = null
@highlightLines()
removeLineHighlights: ->
return unless @highlightedLineNumbers
for line in @highlightedLineNumbers
line.classList.remove('cursor-line')
line.classList.remove('cursor-line-no-selection')
@highlightedLineNumbers = null
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 @getEditor().getSelection().isEmpty()
row = @getEditor().getCursorScreenPosition().row
rowRange = new Range([row, 0], [row, 0])
return if @selectionEmpty and @highlightedRows?.isEqual(rowRange)
@removeLineHighlights()
@addLineHighlight(row, true)
@highlightedRows = rowRange
@selectionEmpty = true
else
selectedRows = @getEditor().getSelection().getScreenRange()
endRow = selectedRows.end.row
endRow-- if selectedRows.end.column is 0
selectedRows = new Range([selectedRows.start.row, 0], [endRow, 0])
return if not @selectionEmpty and @highlightedRows?.isEqual(selectedRows)
@removeLineHighlights()
for row in [selectedRows.start.row..selectedRows.end.row]
@addLineHighlight(row, false)
@highlightedRows = selectedRows
@selectionEmpty = false