From 63270f417432f12ffeacf93f42c77308ea8e6211 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 16 Feb 2016 14:35:12 +0100 Subject: [PATCH] Add TextEditor.prototype.cursorsForScreenRowRange So that `TextEditorPresenter` can avoid to scan through all the cursors to understand whether they're visible on screen. This dramatically reduces the calls to `getScreenRange` and, thus, makes `updateCursorsState` faster for multi-cursor edits. --- src/text-editor-presenter.coffee | 16 ++++++---------- src/text-editor.coffee | 10 ++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index b13bf9036..a36c860ed 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -432,18 +432,14 @@ class TextEditorPresenter return updateCursorsState: -> - @state.content.cursors = {} - @updateCursorState(cursor) for cursor in @model.cursors # using property directly to avoid allocation - return - - updateCursorState: (cursor) -> return unless @startRow? and @endRow? and @hasPixelRectRequirements() and @baseCharacterWidth? - screenRange = cursor.getScreenRange() - return unless cursor.isVisible() and @startRow <= screenRange.start.row < @endRow - pixelRect = @pixelRectForScreenRange(screenRange) - pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0 - @state.content.cursors[cursor.id] = pixelRect + @state.content.cursors = {} + for cursor in @model.cursorsForScreenRowRange(@startRow, @endRow - 1) when cursor.isVisible() + pixelRect = @pixelRectForScreenRange(cursor.getScreenRange()) + pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0 + @state.content.cursors[cursor.id] = pixelRect + return updateOverlaysState: -> return unless @hasOverlayPositionRequirements() diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 2ba45a3ba..55f6d84ad 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -109,6 +109,7 @@ class TextEditor extends Model @emitter = new Emitter @disposables = new CompositeDisposable @cursors = [] + @cursorsByMarkerId = new Map @selections = [] buffer ?= new TextBuffer @@ -1944,10 +1945,18 @@ class TextEditor extends Model getCursorsOrderedByBufferPosition: -> @getCursors().sort (a, b) -> a.compare(b) + cursorsForScreenRowRange: (startScreenRow, endScreenRow) -> + cursors = [] + for marker in @selectionsMarkerLayer.findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow]) + if cursor = @cursorsByMarkerId.get(marker.id) + cursors.push(cursor) + cursors + # Add a cursor based on the given {TextEditorMarker}. addCursor: (marker) -> cursor = new Cursor(editor: this, marker: marker, config: @config) @cursors.push(cursor) + @cursorsByMarkerId.set(marker.id, cursor) @decorateMarker(marker, type: 'line-number', class: 'cursor-line') @decorateMarker(marker, type: 'line-number', class: 'cursor-line-no-selection', onlyHead: true, onlyEmpty: true) @decorateMarker(marker, type: 'line', class: 'cursor-line', onlyEmpty: true) @@ -2446,6 +2455,7 @@ class TextEditor extends Model removeSelection: (selection) -> _.remove(@cursors, selection.cursor) _.remove(@selections, selection) + @cursorsByMarkerId.delete(selection.cursor.marker.id) @emitter.emit 'did-remove-cursor', selection.cursor @emitter.emit 'did-remove-selection', selection