Add specs for single-, triple-, and cmd-clicking

This commit is contained in:
Nathan Sobo
2017-03-09 20:41:42 -07:00
committed by Antonio Scandurra
parent 2996500d90
commit 35753c3a8d
3 changed files with 148 additions and 10 deletions

View File

@@ -646,9 +646,7 @@ describe('TextEditorComponent', () => {
it('selects words on double-click', () => {
const {component, editor} = buildComponent()
const clientX = clientLeftForCharacter(component, 1, 16)
const clientY = clientTopForLine(component, 1)
const {clientX, clientY} = clientPositionForCharacter(component, 1, 16)
component.didMouseDownOnLines({detail: 1, clientX, clientY})
component.didMouseDownOnLines({detail: 2, clientX, clientY})
expect(editor.getSelectedScreenRange()).toEqual([[1, 13], [1, 21]])
@@ -656,13 +654,122 @@ describe('TextEditorComponent', () => {
it('selects lines on triple-click', () => {
const {component, editor} = buildComponent()
const clientX = clientLeftForCharacter(component, 1, 16)
const clientY = clientTopForLine(component, 1)
const {clientX, clientY} = clientPositionForCharacter(component, 1, 16)
component.didMouseDownOnLines({detail: 1, clientX, clientY})
component.didMouseDownOnLines({detail: 2, clientX, clientY})
component.didMouseDownOnLines({detail: 3, clientX, clientY})
expect(editor.getSelectedScreenRange()).toEqual([[1, 0], [2, 0]])
})
it('adds or removes cursors when holding cmd or ctrl when single-clicking', () => {
const {component, editor} = buildComponent()
spyOn(component, 'getPlatform').andCallFake(() => mockedPlatform)
let mockedPlatform = 'darwin'
expect(editor.getCursorScreenPositions()).toEqual([[0, 0]])
// add cursor at 1, 16
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 1, 16), {
detail: 1,
metaKey: true
})
)
expect(editor.getCursorScreenPositions()).toEqual([[0, 0], [1, 16]])
// remove cursor at 0, 0
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 0, 0), {
detail: 1,
metaKey: true
})
)
expect(editor.getCursorScreenPositions()).toEqual([[1, 16]])
// cmd-click cursor at 1, 16 but don't remove it because it's the last one
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 1, 16), {
detail: 1,
metaKey: true
})
)
expect(editor.getCursorScreenPositions()).toEqual([[1, 16]])
// cmd-clicking within a selection destroys it
editor.addSelectionForScreenRange([[2, 10], [2, 15]])
expect(editor.getSelectedScreenRanges()).toEqual([
[[1, 16], [1, 16]],
[[2, 10], [2, 15]]
])
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 2, 13), {
detail: 1,
metaKey: true
})
)
expect(editor.getSelectedScreenRanges()).toEqual([
[[1, 16], [1, 16]]
])
// ctrl-click does not add cursors on macOS
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 1, 4), {
detail: 1,
ctrlKey: true
})
)
expect(editor.getCursorScreenPositions()).toEqual([[1, 4]])
mockedPlatform = 'win32'
// ctrl-click adds cursors on platforms *other* than macOS
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 1, 16), {
detail: 1,
ctrlKey: true
})
)
expect(editor.getCursorScreenPositions()).toEqual([[1, 4], [1, 16]])
})
it('adds word selections when holding cmd or ctrl when double-clicking', () => {
const {component, editor} = buildComponent()
editor.addCursorAtScreenPosition([1, 16])
expect(editor.getCursorScreenPositions()).toEqual([[0, 0], [1, 16]])
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 1, 16), {
detail: 1,
metaKey: true
})
)
component.didMouseDownOnLines(
Object.assign(clientPositionForCharacter(component, 1, 16), {
detail: 2,
metaKey: true
})
)
expect(editor.getSelectedScreenRanges()).toEqual([
[[0, 0], [0, 0]],
[[1, 13], [1, 21]]
])
})
it('adds line selections when holding cmd or ctrl when triple-clicking', () => {
const {component, editor} = buildComponent()
editor.addCursorAtScreenPosition([1, 16])
expect(editor.getCursorScreenPositions()).toEqual([[0, 0], [1, 16]])
const {clientX, clientY} = clientPositionForCharacter(component, 1, 16)
component.didMouseDownOnLines({detail: 1, metaKey: true, clientX, clientY})
component.didMouseDownOnLines({detail: 2, metaKey: true, clientX, clientY})
component.didMouseDownOnLines({detail: 3, metaKey: true, clientX, clientY})
expect(editor.getSelectedScreenRanges()).toEqual([
[[0, 0], [0, 0]],
[[1, 0], [2, 0]]
])
})
})
})
@@ -726,6 +833,13 @@ function clientLeftForCharacter (component, row, column) {
}
}
function clientPositionForCharacter (component, row, column) {
return {
clientX: clientLeftForCharacter(component, row, column),
clientY: clientTopForLine(component, row)
}
}
function lineNumberNodeForScreenRow (component, row) {
const gutterElement = component.refs.lineNumberGutter.element
const tileStartRow = component.tileStartRowForRow(row)

View File

@@ -393,6 +393,11 @@ class TextEditorComponent {
})
}
// This is easier to mock
getPlatform () {
return process.platform
}
queryDecorationsToRender () {
this.decorationsToRender.lineNumbers.clear()
this.decorationsToRender.lines.clear()
@@ -739,14 +744,27 @@ class TextEditorComponent {
const {model} = this.props
const screenPosition = this.screenPositionForMouseEvent(event)
const addOrRemoveSelection = event.metaKey || (event.ctrlKey && this.getPlatform() !== 'darwin')
switch (event.detail) {
case 1:
model.setCursorScreenPosition(screenPosition)
if (addOrRemoveSelection) {
const existingSelection = model.getSelectionAtScreenPosition(screenPosition)
if (existingSelection) {
if (model.hasMultipleCursors()) existingSelection.destroy()
} else {
model.addCursorAtScreenPosition(screenPosition)
}
} else {
model.setCursorScreenPosition(screenPosition)
}
break
case 2:
if (addOrRemoveSelection) model.addCursorAtScreenPosition(screenPosition)
model.getLastSelection().selectWord({autoscroll: false})
break
case 3:
if (addOrRemoveSelection) model.addCursorAtScreenPosition(screenPosition)
model.getLastSelection().selectLine(null, {autoscroll: false})
break
}

View File

@@ -2096,9 +2096,9 @@ class TextEditor extends Model
#
# Returns the first matched {Cursor} or undefined
getCursorAtScreenPosition: (position) ->
for cursor in @cursors
return cursor if cursor.getScreenPosition().isEqual(position)
undefined
if selection = @getSelectionAtScreenPosition(position)
if selection.getHeadScreenPosition().isEqual(position)
selection.cursor
# Essential: Get the position of the most recently added cursor in screen
# coordinates.
@@ -2647,6 +2647,12 @@ class TextEditor extends Model
@createLastSelectionIfNeeded()
_.last(@selections)
getSelectionAtScreenPosition: (position) ->
debugger if global.debug
markers = @selectionsMarkerLayer.findMarkers(containsScreenPosition: position)
if markers.length > 0
@cursorsByMarkerId.get(markers[0].id).selection
# Extended: Get current {Selection}s.
#
# Returns: An {Array} of {Selection}s.