mirror of
https://github.com/atom/atom.git
synced 2026-01-25 06:48:28 -05:00
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:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user