mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 23:48:05 +03:00
Replace skipAtomicTokens with clip
When clipping a screen position, callers used to have to pick between clipping to the left edge or the right edge when the position was in the middle of an atomic token. This change allows them to choose the closest edge, and makes this the default. This makes selecting hard tabs (or any other atomic tokens) work in a similar manner as in other text editors; that is, when clicking near the middle of a tab, the insertion point will move to the closest edge rather than the left edge.
This commit is contained in:
parent
372fb49c88
commit
5a3f2035a1
@ -638,8 +638,11 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.outermostFoldsInBufferRowRange(3, 18)).toEqual [fold1, fold3, fold5]
|
||||
expect(displayBuffer.outermostFoldsInBufferRowRange(5, 16)).toEqual [fold3]
|
||||
|
||||
describe "::clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", ->
|
||||
describe "::clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, clip: 'closest')", ->
|
||||
beforeEach ->
|
||||
tabLength = 4
|
||||
|
||||
displayBuffer.setTabLength(tabLength)
|
||||
displayBuffer.setSoftWrapped(true)
|
||||
displayBuffer.setEditorWidthInChars(50)
|
||||
|
||||
@ -698,19 +701,28 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.clipScreenPosition([3, 58], wrapAtSoftNewlines: true)).toEqual [4, 4]
|
||||
expect(displayBuffer.clipScreenPosition([3, 1000], wrapAtSoftNewlines: true)).toEqual [4, 4]
|
||||
|
||||
describe "when skipAtomicTokens is false (the default)", ->
|
||||
it "clips screen positions in the middle of atomic tab characters to the beginning of the character", ->
|
||||
describe "when clip is 'closest' (the default)", ->
|
||||
it "clips screen positions in the middle of atomic tab characters to the closest edge of the character", ->
|
||||
buffer.insert([0, 0], '\t')
|
||||
expect(displayBuffer.clipScreenPosition([0, 0])).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, 1])).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, 2])).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, tabLength-1])).toEqual [0, tabLength]
|
||||
expect(displayBuffer.clipScreenPosition([0, tabLength])).toEqual [0, tabLength]
|
||||
|
||||
describe "when skipAtomicTokens is true", ->
|
||||
describe "when clip is 'backward'", ->
|
||||
it "clips screen positions in the middle of atomic tab characters to the beginning of the character", ->
|
||||
buffer.insert([0, 0], '\t')
|
||||
expect(displayBuffer.clipScreenPosition([0, 0], clip: 'backward')).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, tabLength-1], clip: 'backward')).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, tabLength], clip: 'backward')).toEqual [0, tabLength]
|
||||
|
||||
describe "when clip is 'forward'", ->
|
||||
it "clips screen positions in the middle of atomic tab characters to the end of the character", ->
|
||||
buffer.insert([0, 0], '\t')
|
||||
expect(displayBuffer.clipScreenPosition([0, 0], skipAtomicTokens: true)).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, 1], skipAtomicTokens: true)).toEqual [0, tabLength]
|
||||
expect(displayBuffer.clipScreenPosition([0, tabLength], skipAtomicTokens: true)).toEqual [0, tabLength]
|
||||
expect(displayBuffer.clipScreenPosition([0, 0], clip: 'forward')).toEqual [0, 0]
|
||||
expect(displayBuffer.clipScreenPosition([0, 1], clip: 'forward')).toEqual [0, tabLength]
|
||||
expect(displayBuffer.clipScreenPosition([0, tabLength], clip: 'forward')).toEqual [0, tabLength]
|
||||
|
||||
describe "::screenPositionForBufferPosition(bufferPosition, options)", ->
|
||||
it "clips the specified buffer position", ->
|
||||
|
@ -305,7 +305,7 @@ class Cursor extends Model
|
||||
columnCount-- # subtract 1 for the row move
|
||||
|
||||
column = column - columnCount
|
||||
@setScreenPosition({row, column})
|
||||
@setScreenPosition({row, column}, clip: 'backward')
|
||||
|
||||
# Public: Moves the cursor right one screen column.
|
||||
#
|
||||
@ -332,7 +332,7 @@ class Cursor extends Model
|
||||
columnsRemainingInLine = rowLength
|
||||
|
||||
column = column + columnCount
|
||||
@setScreenPosition({row, column}, skipAtomicTokens: true, wrapBeyondNewlines: true, wrapAtSoftNewlines: true)
|
||||
@setScreenPosition({row, column}, clip: 'forward', wrapBeyondNewlines: true, wrapAtSoftNewlines: true)
|
||||
|
||||
# Public: Moves the cursor to the top of the buffer.
|
||||
moveToTop: ->
|
||||
|
@ -393,7 +393,7 @@ class Selection extends Model
|
||||
if options.select
|
||||
@setBufferRange(newBufferRange, reversed: wasReversed)
|
||||
else
|
||||
@cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed
|
||||
@cursor.setBufferPosition(newBufferRange.end, clip: 'forward') if wasReversed
|
||||
|
||||
if autoIndentFirstLine
|
||||
@editor.setIndentationForBufferRow(oldBufferRange.start.row, desiredIndentLevel)
|
||||
|
@ -41,10 +41,20 @@ class TokenizedLine
|
||||
copy: ->
|
||||
new TokenizedLine({@tokens, @lineEnding, @ruleStack, @startBufferColumn, @fold})
|
||||
|
||||
# This clips a given screen column to a valid column that's within the line
|
||||
# and not in the middle of any atomic tokens.
|
||||
#
|
||||
# column - A {Number} representing the column to clip
|
||||
# options - A hash with the key clip. Valid values for this key:
|
||||
# 'closest' (default): clip to the closest edge of an atomic token.
|
||||
# 'forward': clip to the forward edge.
|
||||
# 'backward': clip to the backward edge.
|
||||
#
|
||||
# Returns a {Number} representing the clipped column.
|
||||
clipScreenColumn: (column, options={}) ->
|
||||
return 0 if @tokens.length == 0
|
||||
|
||||
{ skipAtomicTokens } = options
|
||||
{ clip } = options
|
||||
column = Math.min(column, @getMaxScreenColumn())
|
||||
|
||||
tokenStartColumn = 0
|
||||
@ -55,10 +65,15 @@ class TokenizedLine
|
||||
if @isColumnInsideSoftWrapIndentation(tokenStartColumn)
|
||||
@softWrapIndentationDelta
|
||||
else if token.isAtomic and tokenStartColumn < column
|
||||
if skipAtomicTokens
|
||||
if clip == 'forward'
|
||||
tokenStartColumn + token.screenDelta
|
||||
else
|
||||
else if clip == 'backward'
|
||||
tokenStartColumn
|
||||
else #'closest'
|
||||
if column > tokenStartColumn + (token.screenDelta / 2)
|
||||
tokenStartColumn + token.screenDelta
|
||||
else
|
||||
tokenStartColumn
|
||||
else
|
||||
column
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user