Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Add showCursorOnSelection config #13664

Merged
merged 1 commit into from
Jan 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion spec/text-editor-component-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1347,7 +1347,19 @@ describe('TextEditorComponent', function () {
expect(cursorsNode.classList.contains('blink-off')).toBe(true)
})

it('does not render cursors that are associated with non-empty selections', function () {
it('renders cursors that are associated with empty selections', function () {
editor.update({showCursorOnSelection: true})
editor.setSelectedScreenRange([[0, 4], [4, 6]])
editor.addCursorAtScreenPosition([6, 8])
runAnimationFrames()
let cursorNodes = componentNode.querySelectorAll('.cursor')
expect(cursorNodes.length).toBe(2)
expect(cursorNodes[0].style['-webkit-transform']).toBe('translate(' + (Math.round(6 * charWidth)) + 'px, ' + (4 * lineHeightInPixels) + 'px)')
expect(cursorNodes[1].style['-webkit-transform']).toBe('translate(' + (Math.round(8 * charWidth)) + 'px, ' + (6 * lineHeightInPixels) + 'px)')
})

it('does not render cursors that are associated with non-empty selections when showCursorOnSelection is false', function () {
editor.update({showCursorOnSelection: false})
editor.setSelectedScreenRange([[0, 4], [4, 6]])
editor.addCursorAtScreenPosition([6, 8])
runAnimationFrames()
Expand Down
4 changes: 4 additions & 0 deletions spec/text-editor-presenter-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,7 @@ describe "TextEditorPresenter", ->
getState(presenter).content.cursors[presenter.model.getCursors()[cursorIndex].id]

it "contains pixelRects for empty selections that are visible on screen", ->
editor.update({showCursorOnSelection: false})
editor.setSelectedBufferRanges([
[[1, 2], [1, 2]],
[[2, 4], [2, 4]],
Expand Down Expand Up @@ -1627,6 +1628,7 @@ describe "TextEditorPresenter", ->
expect(getState(presenter).content.cursors).not.toEqual({})

it "updates when block decorations change", ->
editor.update({showCursorOnSelection: false})
editor.setSelectedBufferRanges([
[[1, 2], [1, 2]],
[[2, 4], [2, 4]],
Expand Down Expand Up @@ -1704,6 +1706,7 @@ describe "TextEditorPresenter", ->
expect(stateForCursor(presenter, 0)).toEqual {top: 20, left: 10 * 22, width: 10, height: 10}

it "updates when ::explicitHeight changes", ->
editor.update({showCursorOnSelection: false})
editor.setSelectedBufferRanges([
[[1, 2], [1, 2]],
[[2, 4], [2, 4]],
Expand Down Expand Up @@ -1757,6 +1760,7 @@ describe "TextEditorPresenter", ->
expect(stateForCursor(presenter, 0)).toEqual {top: 1 * 10, left: (3 * 10) + 20, width: 20, height: 10}

it "updates when cursors are added, moved, hidden, shown, or destroyed", ->
editor.update({showCursorOnSelection: false})
editor.setSelectedBufferRanges([
[[1, 2], [1, 2]],
[[3, 4], [3, 5]]
Expand Down
13 changes: 13 additions & 0 deletions spec/text-editor-registry-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,19 @@ describe('TextEditorRegistry', function () {
expect(editor.hasAtomicSoftTabs()).toBe(true)
})

it('enables or disables cursor on selection visibility based on the config', async function () {
editor.update({showCursorOnSelection: true})
expect(editor.getShowCursorOnSelection()).toBe(true)

atom.config.set('editor.showCursorOnSelection', false)
registry.maintainConfig(editor)
await initialPackageActivation
expect(editor.getShowCursorOnSelection()).toBe(false)

atom.config.set('editor.showCursorOnSelection', true)
expect(editor.getShowCursorOnSelection()).toBe(true)
})

it('enables or disables line numbers based on the config', async function () {
editor.update({showLineNumbers: true})
expect(editor.showLineNumbers).toBe(true)
Expand Down
61 changes: 57 additions & 4 deletions spec/text-editor-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ describe "TextEditor", ->

describe ".copy()", ->
it "returns a different editor with the same initial state", ->
editor.update({autoHeight: false, autoWidth: true})
expect(editor.getAutoHeight()).toBeFalsy()
expect(editor.getAutoWidth()).toBeFalsy()
expect(editor.getShowCursorOnSelection()).toBeTruthy()

editor.update({autoHeight: true, autoWidth: true, showCursorOnSelection: false})
editor.setSelectedBufferRange([[1, 2], [3, 4]])
editor.addSelectionForBufferRange([[5, 6], [7, 8]], reversed: true)
editor.firstVisibleScreenRow = 5
Expand All @@ -105,7 +109,8 @@ describe "TextEditor", ->
expect(editor2.getFirstVisibleScreenColumn()).toBe 5
expect(editor2.isFoldedAtBufferRow(4)).toBeTruthy()
expect(editor2.getAutoWidth()).toBeTruthy()
expect(editor2.getAutoHeight()).toBeFalsy()
expect(editor2.getAutoHeight()).toBeTruthy()
expect(editor2.getShowCursorOnSelection()).toBeFalsy()

# editor2 can now diverge from its origin edit session
editor2.getLastSelection().setBufferRange([[2, 1], [4, 3]])
Expand Down Expand Up @@ -1858,7 +1863,7 @@ describe "TextEditor", ->
[[4, 25], [4, 29]]
]
for cursor in editor.getCursors()
expect(cursor.isVisible()).toBeFalsy()
expect(cursor.isVisible()).toBeTruthy()

it "skips lines that are too short to create a non-empty selection", ->
editor.setSelectedBufferRange([[3, 31], [3, 38]])
Expand Down Expand Up @@ -1991,7 +1996,7 @@ describe "TextEditor", ->
[[2, 37], [2, 40]]
]
for cursor in editor.getCursors()
expect(cursor.isVisible()).toBeFalsy()
expect(cursor.isVisible()).toBeTruthy()

it "skips lines that are too short to create a non-empty selection", ->
editor.setSelectedBufferRange([[6, 31], [6, 38]])
Expand Down Expand Up @@ -2161,6 +2166,54 @@ describe "TextEditor", ->
editor.setCursorScreenPosition([3, 3])
expect(selection.isEmpty()).toBeTruthy()

describe "cursor visibility while there is a selection", ->
describe "when showCursorOnSelection is true", ->
it "is visible while there is no selection", ->
expect(selection.isEmpty()).toBeTruthy()
expect(editor.getShowCursorOnSelection()).toBeTruthy()
expect(editor.getCursors().length).toBe 1
expect(editor.getCursors()[0].isVisible()).toBeTruthy()

it "is visible while there is a selection", ->
expect(selection.isEmpty()).toBeTruthy()
editor.setSelectedBufferRange([[1, 2], [1, 5]])
expect(selection.isEmpty()).toBeFalsy()
expect(editor.getCursors().length).toBe 1
expect(editor.getCursors()[0].isVisible()).toBeTruthy()

it "is visible while there are multiple selections", ->
expect(editor.getSelections().length).toBe 1
editor.setSelectedBufferRanges([[[1, 2], [1, 5]], [[2, 2], [2, 5]]])
expect(editor.getSelections().length).toBe 2
expect(editor.getCursors().length).toBe 2
expect(editor.getCursors()[0].isVisible()).toBeTruthy()
expect(editor.getCursors()[1].isVisible()).toBeTruthy()

describe "when showCursorOnSelection is false", ->
it "is visible while there is no selection", ->
editor.update({showCursorOnSelection: false})
expect(selection.isEmpty()).toBeTruthy()
expect(editor.getShowCursorOnSelection()).toBeFalsy()
expect(editor.getCursors().length).toBe 1
expect(editor.getCursors()[0].isVisible()).toBeTruthy()

it "is not visible while there is a selection", ->
editor.update({showCursorOnSelection: false})
expect(selection.isEmpty()).toBeTruthy()
editor.setSelectedBufferRange([[1, 2], [1, 5]])
expect(selection.isEmpty()).toBeFalsy()
expect(editor.getCursors().length).toBe 1
expect(editor.getCursors()[0].isVisible()).toBeFalsy()

it "is not visible while there are multiple selections", ->
editor.update({showCursorOnSelection: false})
expect(editor.getSelections().length).toBe 1
editor.setSelectedBufferRanges([[[1, 2], [1, 5]], [[2, 2], [2, 5]]])
expect(editor.getSelections().length).toBe 2
expect(editor.getCursors().length).toBe 2
expect(editor.getCursors()[0].isVisible()).toBeFalsy()
expect(editor.getCursors()[1].isVisible()).toBeFalsy()

it "does not share selections between different edit sessions for the same buffer", ->
editor2 = null
waitsForPromise ->
Expand Down
5 changes: 5 additions & 0 deletions src/config-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ const configSchema = {
default: 1.5,
description: 'Height of editor lines, as a multiplier of font size.'
},
showCursorOnSelection: {
type: 'boolean',
'default': true,
description: 'Show cursor while there is a selection.'
},
showInvisibles: {
type: 'boolean',
default: false,
Expand Down
15 changes: 13 additions & 2 deletions src/cursor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ EmptyLineRegExp = /(\r\n[\t ]*\r\n)|(\n[\t ]*\n)/g
# of a {DisplayMarker}.
module.exports =
class Cursor extends Model
showCursorOnSelection: null
screenPosition: null
bufferPosition: null
goalColumn: null
visible: true

# Instantiated by a {TextEditor}
constructor: ({@editor, @marker, id}) ->
constructor: ({@editor, @marker, @showCursorOnSelection, id}) ->
@emitter = new Emitter

@showCursorOnSelection ?= true

@assignId(id)
@updateVisibility()

Expand Down Expand Up @@ -575,7 +578,10 @@ class Cursor extends Model
isVisible: -> @visible

updateVisibility: ->
@setVisible(@marker.getBufferRange().isEmpty())
if @showCursorOnSelection
@setVisible(true)
else
@setVisible(@marker.getBufferRange().isEmpty())

###
Section: Comparing to another cursor
Expand Down Expand Up @@ -645,6 +651,11 @@ class Cursor extends Model
Section: Private
###

setShowCursorOnSelection: (value) ->
if value isnt @showCursorOnSelection
@showCursorOnSelection = value
@updateVisibility()

getNonWordCharacters: ->
@editor.getNonWordCharacters(@getScopeDescriptor().getScopesArray())

Expand Down
1 change: 1 addition & 0 deletions src/text-editor-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const EDITOR_PARAMS_BY_SETTING_KEY = [
['editor.showInvisibles', 'showInvisibles'],
['editor.tabLength', 'tabLength'],
['editor.invisibles', 'invisibles'],
['editor.showCursorOnSelection', 'showCursorOnSelection'],
['editor.showIndentGuide', 'showIndentGuide'],
['editor.showLineNumbers', 'showLineNumbers'],
['editor.softWrap', 'softWrapped'],
Expand Down
20 changes: 17 additions & 3 deletions src/text-editor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class TextEditor extends Model
buffer: null
languageMode: null
cursors: null
showCursorOnSelection: null
selections: null
suppressSelectionMerging: false
selectionFlashDuration: 500
Expand Down Expand Up @@ -133,7 +134,8 @@ class TextEditor extends Model
@mini, @placeholderText, lineNumberGutterVisible, @largeFileMode,
@assert, grammar, @showInvisibles, @autoHeight, @autoWidth, @scrollPastEnd, @editorWidthInChars,
@tokenizedBuffer, @displayLayer, @invisibles, @showIndentGuide,
@softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength
@softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength,
@showCursorOnSelection
} = params

@assert ?= (condition) -> condition
Expand All @@ -153,6 +155,7 @@ class TextEditor extends Model
tabLength ?= 2
@autoIndent ?= true
@autoIndentOnPaste ?= true
@showCursorOnSelection ?= true
@undoGroupingInterval ?= 300
@nonWordCharacters ?= "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-…"
@softWrapped ?= false
Expand Down Expand Up @@ -342,6 +345,12 @@ class TextEditor extends Model
if value isnt @autoWidth
@autoWidth = value
@presenter?.didChangeAutoWidth()

when 'showCursorOnSelection'
if value isnt @showCursorOnSelection
@showCursorOnSelection = value
cursor.setShowCursorOnSelection(value) for cursor in @getCursors()

else
throw new TypeError("Invalid TextEditor parameter: '#{param}'")

Expand Down Expand Up @@ -722,7 +731,7 @@ class TextEditor extends Model
tabLength: @tokenizedBuffer.getTabLength(),
@firstVisibleScreenRow, @firstVisibleScreenColumn,
@assert, displayLayer, grammar: @getGrammar(),
@autoWidth, @autoHeight
@autoWidth, @autoHeight, @showCursorOnSelection
})

# Controls visibility based on the given {Boolean}.
Expand Down Expand Up @@ -2269,7 +2278,7 @@ class TextEditor extends Model

# Add a cursor based on the given {DisplayMarker}.
addCursor: (marker) ->
cursor = new Cursor(editor: this, marker: marker)
cursor = new Cursor(editor: this, marker: marker, showCursorOnSelection: @showCursorOnSelection)
@cursors.push(cursor)
@cursorsByMarkerId.set(marker.id, cursor)
@decorateMarker(marker, type: 'line-number', class: 'cursor-line')
Expand Down Expand Up @@ -3466,6 +3475,11 @@ class TextEditor extends Model
# Returns a positive {Number}.
getScrollSensitivity: -> @scrollSensitivity

# Experimental: Does this editor show cursors while there is a selection?
#
# Returns a positive {Boolean}.
getShowCursorOnSelection: -> @showCursorOnSelection

# Experimental: Are line numbers enabled for this editor?
#
# Returns a {Boolean}
Expand Down