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.
This commit is contained in:
Antonio Scandurra
2016-02-16 14:35:12 +01:00
parent 73f497afe3
commit 63270f4174
2 changed files with 16 additions and 10 deletions

View File

@@ -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()

View File

@@ -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