diff --git a/src/app/cursor-view.coffee b/src/app/cursor-view.coffee index 7f620e7c1..4d72e07c8 100644 --- a/src/app/cursor-view.coffee +++ b/src/app/cursor-view.coffee @@ -17,6 +17,10 @@ class CursorView extends View initialize: (@cursor, @editor) -> @anchor = new Anchor(@editor, cursor.getScreenPosition()) @selection = @editor.compositeSelection.addSelectionForCursor(this) + @cursor.on 'change-screen-position', (position, options) => + options.fromModel = true + @setScreenPosition(position, options) + @cursor.on 'destroy', => @remove() afterAttach: (onDom) -> return unless onDom @@ -24,32 +28,38 @@ class CursorView extends View @editor.syncCursorAnimations() handleBufferChange: (e) -> - @anchor.handleBufferChange(e) - @refreshScreenPosition() + @cursor.handleBufferChange(e) + # @anchor.handleBufferChange(e) + # @refreshScreenPosition() @trigger 'cursor-move', bufferChange: true remove: -> @editor.compositeCursor.removeCursor(this) @editor.compositeSelection.removeSelectionForCursor(this) + @cursor.off() super getBufferPosition: -> - @anchor.getBufferPosition() + @cursor.getBufferPosition() setBufferPosition: (bufferPosition, options={}) -> - @anchor.setBufferPosition(bufferPosition, options) - @refreshScreenPosition() - @trigger 'cursor-move', bufferChange: false - @clearSelection() + @cursor.setBufferPosition(bufferPosition, options) + # @anchor.setBufferPosition(bufferPosition, options) + # @refreshScreenPosition() + # @trigger 'cursor-move', bufferChange: false + # @clearSelection() getScreenPosition: -> @anchor.getScreenPosition() setScreenPosition: (position, options={}) -> - @anchor.setScreenPosition(position, options) - @refreshScreenPosition(position, options) - @trigger 'cursor-move', bufferChange: false - @clearSelection() + if options.fromModel + @anchor.setScreenPosition(position, options) + @refreshScreenPosition() + @trigger 'cursor-move', bufferChange: options.bufferChange + @clearSelection() unless options.bufferChange + else + @cursor.setScreenPosition(position, options) refreshScreenPosition: -> @goalColumn = null @@ -73,18 +83,6 @@ class CursorView extends View isOnEOL: -> @getScreenPosition().column == @getCurrentBufferLine().length - moveUp: -> - { row, column } = @getScreenPosition() - column = @goalColumn if @goalColumn? - @setScreenPosition({row: row - 1, column: column}) - @goalColumn = column - - moveDown: -> - { row, column } = @getScreenPosition() - column = @goalColumn if @goalColumn? - @setScreenPosition({row: row + 1, column: column}) - @goalColumn = column - moveToNextWord: -> bufferPosition = @getBufferPosition() range = [bufferPosition, @editor.getEofPosition()] diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 0c37519f4..e60aa81e8 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -1,25 +1,53 @@ Point = require 'point' Anchor = require 'new-anchor' +EventEmitter = require 'event-emitter' +_ = require 'underscore' module.exports = class Cursor screenPosition: null bufferPosition: null + goalColumn: null constructor: ({@editSession, screenPosition, bufferPosition}) -> @anchor = new Anchor(@editSession) @setScreenPosition(screenPosition) if screenPosition @setBufferPosition(bufferPosition) if bufferPosition - setScreenPosition: (screenPosition) -> - @anchor.setScreenPosition(screenPosition) + setScreenPosition: (screenPosition, options) -> + @anchor.setScreenPosition(screenPosition, options) + @goalColumn = null + @trigger 'change-screen-position', @getScreenPosition(), bufferChange: false getScreenPosition: -> @anchor.getScreenPosition() - setBufferPosition: (bufferPosition) -> - @anchor.setBufferPosition(bufferPosition) + setBufferPosition: (bufferPosition, options) -> + @anchor.setBufferPosition(bufferPosition, options) + @goalColumn = null + @trigger 'change-screen-position', @getScreenPosition(), bufferChange: false getBufferPosition: -> @anchor.getBufferPosition() + handleBufferChange: (e) -> + @anchor.handleBufferChange(e) + @trigger 'change-screen-position', @getScreenPosition(), bufferChange: true + + moveUp: -> + { row, column } = @getScreenPosition() + column = @goalColumn if @goalColumn? + @setScreenPosition({row: row - 1, column: column}) + @goalColumn = column + + moveDown: -> + { row, column } = @getScreenPosition() + column = @goalColumn if @goalColumn? + @setScreenPosition({row: row + 1, column: column}) + @goalColumn = column + + destroy: -> + @editSession.removeCursor(this) + @trigger 'destroy' + +_.extend Cursor.prototype, EventEmitter diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 19b7265aa..700f868d8 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -64,14 +64,42 @@ class EditSession @trigger 'add-cursor', cursor cursor + removeCursor: (cursor) -> + _.remove(@cursors, cursor) + + getLastCursor: -> + _.last(@cursors) + setCursorScreenPosition: (position) -> - @getLastCursor().setScreenPosition(position) + @moveCursors (cursor) -> cursor.setScreenPosition(position) getCursorScreenPosition: -> @getLastCursor().getScreenPosition() - getLastCursor: -> - _.last(@cursors) + setCursorBufferPosition: (position) -> + @moveCursors (cursor) -> cursor.setBufferPosition(position) + + getCursorBufferPosition: -> + @getLastCursor().getBufferPosition() + + moveCursorUp: -> + @moveCursors (cursor) -> cursor.moveUp() + + moveCursorDown: -> + @moveCursors (cursor) -> cursor.moveDown() + + moveCursors: (fn) -> + fn(cursor) for cursor in @getCursors() + @mergeCursors() + + mergeCursors: -> + positions = [] + for cursor in new Array(@getCursors()...) + position = cursor.getBufferPosition().toString() + if position in positions + cursor.destroy() + else + positions.push(position) isEqual: (other) -> return false unless other instanceof EditSession diff --git a/src/app/editor.coffee b/src/app/editor.coffee index a43f726a5..85bb41ecf 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -640,8 +640,8 @@ class Editor extends View @updateRenderedLines() getCursors: -> @compositeCursor.getCursors() - moveCursorUp: -> @compositeCursor.moveUp() - moveCursorDown: -> @compositeCursor.moveDown() + moveCursorUp: -> @activeEditSession.moveCursorUp() + moveCursorDown: -> @activeEditSession.moveCursorDown() moveCursorRight: -> @compositeCursor.moveRight() moveCursorLeft: -> @compositeCursor.moveLeft() moveCursorToNextWord: -> @compositeCursor.moveToNextWord() @@ -652,10 +652,10 @@ class Editor extends View moveCursorToBeginningOfLine: -> @compositeCursor.moveToBeginningOfLine() moveCursorToFirstCharacterOfLine: -> @compositeCursor.moveToFirstCharacterOfLine() moveCursorToEndOfLine: -> @compositeCursor.moveToEndOfLine() - setCursorScreenPosition: (position) -> @compositeCursor.setScreenPosition(position) - getCursorScreenPosition: -> @compositeCursor.getCursor().getScreenPosition() - setCursorBufferPosition: (position) -> @compositeCursor.setBufferPosition(position) - getCursorBufferPosition: -> @compositeCursor.getCursor().getBufferPosition() + setCursorScreenPosition: (position) -> @activeEditSession.setCursorScreenPosition(position) + getCursorScreenPosition: -> @activeEditSession.getCursorScreenPosition() + setCursorBufferPosition: (position) -> @activeEditSession.setCursorBufferPosition(position) + getCursorBufferPosition: -> @activeEditSession.getCursorBufferPosition() getSelection: (index) -> @compositeSelection.getSelection(index) getSelections: -> @compositeSelection.getSelections() diff --git a/src/app/event-emitter.coffee b/src/app/event-emitter.coffee index f7dea698b..8b28395ba 100644 --- a/src/app/event-emitter.coffee +++ b/src/app/event-emitter.coffee @@ -16,13 +16,13 @@ module.exports = @afterSubscribe?() - trigger: (eventName, event) -> + trigger: (eventName, args...) -> [eventName, namespace] = eventName.split('.') if namespace - @eventHandlersByNamespace?[namespace]?[eventName]?.forEach (handler) -> handler(event) + @eventHandlersByNamespace?[namespace]?[eventName]?.forEach (handler) -> handler(args...) else - @eventHandlersByEventName?[eventName]?.forEach (handler) -> handler(event) + @eventHandlersByEventName?[eventName]?.forEach (handler) -> handler(args...) off: (eventName='', handler) -> [eventName, namespace] = eventName.split('.') diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 19e128457..61267b932 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -208,10 +208,10 @@ class Selection extends View @modifySelection => @cursor.moveLeft() selectUp: -> - @modifySelection => @cursor.moveUp() + @modifySelection => @cursor.cursor.moveUp() selectDown: -> - @modifySelection => @cursor.moveDown() + @modifySelection => @cursor.cursor.moveDown() selectToTop: -> @modifySelection => @cursor.moveToTop()