Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update cursors with 'keyboard' kind Selections #5050

Closed
wants to merge 10 commits into from
91 changes: 64 additions & 27 deletions src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,25 @@ export class ModeHandler implements vscode.Disposable {
// We shouldn't go to visual mode on any other mode, because the other visual modes are handled
// very differently than vscode so only our extension will create them. And the other modes
// like the plugin modes shouldn't be changed or else it might mess up the plugins actions.
this._logger.debug('Selections: Creating Multi Cursor Visual Selection!');
if (e.kind === vscode.TextEditorSelectionChangeKind.Keyboard) {
this.vimState.cursors = e.textEditor.selections.map(
(sel) =>
new Range(
Position.FromVSCodePosition(sel.anchor),
sel.anchor.isBefore(sel.active)
? // This is another case where we are changing our cursor so that the selection looks right
Position.FromVSCodePosition(sel.active).getRight()
: Position.FromVSCodePosition(sel.active)
)
);
}
await this.setCurrentMode(Mode.Visual);
// Here we need our updateView to draw the selection because we want vscode to include the initial
// character, and by doing it through out updateView we make sure that any resultant selection
// change event will be ignored.
await this.updateView(this.vimState);
return;
}
return this.updateView(this.vimState);
}
Expand All @@ -189,36 +207,55 @@ export class ModeHandler implements vscode.Disposable {
*/
if (e.kind !== vscode.TextEditorSelectionChangeKind.Mouse) {
if (selection) {
if (e.kind === vscode.TextEditorSelectionChangeKind.Command) {
// This 'Command' kind is triggered when using a command like 'editor.action.smartSelect.grow'
// but it is also triggered when we set the 'editor.selections' on 'updateView'.
if (
[Mode.Normal, Mode.Visual, Mode.Insert, Mode.Replace].includes(
this.vimState.currentMode
)
) {
// Since the selections weren't ignored then probably we got change of selection from
// a command, so we need to update our start and stop positions. This is where commands
// like 'editor.action.smartSelect.grow' are handled.
if (this.vimState.currentMode === Mode.Visual) {
this._logger.debug('Selections: Updating Visual Selection!');
this.vimState.cursorStopPosition = Position.FromVSCodePosition(selection.active);
this.vimState.cursorStartPosition = Position.FromVSCodePosition(selection.anchor);
await this.updateView(this.vimState, { drawSelection: false, revealRange: false });
return;
} else if (!selection.active.isEqual(selection.anchor)) {
this._logger.debug('Selections: Creating Visual Selection from command!');
this.vimState.cursorStopPosition = Position.FromVSCodePosition(selection.active);
this.vimState.cursorStartPosition = Position.FromVSCodePosition(selection.anchor);
await this.setCurrentMode(Mode.Visual);
await this.updateView(this.vimState, { drawSelection: false, revealRange: false });
return;
if (
[Mode.Normal, Mode.Visual, Mode.Insert, Mode.Replace].includes(this.vimState.currentMode)
) {
// Since the selections weren't ignored then probably we got change of selection from
// a command, so we need to update our start and stop positions. This is where commands
// like 'editor.action.smartSelect.grow' are handled.
if (this.vimState.currentMode === Mode.Visual) {
this._logger.debug('Selections: Updating Visual Selection!');
const active = Position.FromVSCodePosition(selection.active);
const anchor = Position.FromVSCodePosition(selection.anchor);
this.vimState.cursorStopPosition = active;
this.vimState.cursorStartPosition = anchor;
if (e.kind === vscode.TextEditorSelectionChangeKind.Keyboard) {
if (selection.anchor.isAfter(selection.active)) {
this.vimState.cursorStartPosition = anchor.getLeft();
}
}
// Here we need our updateView to draw the selection because even though we don't need to
// change the vscode selection, in some situations when you trigger an initial selection
// and then update that selection these events will be triggered only after vscode has done
// both selection changes and in that situation we will get all the events in a row and since
// when creating the visual selection the first time (the code block below this) we change
// the selection, then we need to change the selection on the updates as well or else we
// would revert the vscode selection back to the initial one. (This issue is noticeable when
// using the VSpaceCode extension that shows a QuickPick menu that allows you to call commands
// that change the selection in vscode, but we will only get this 'handleSelectionChange'
// function called with all those changes after the user closes the QuickPick menu)
await this.updateView(this.vimState);
return;
} else if (!selection.active.isEqual(selection.anchor)) {
this._logger.debug('Selections: Creating Visual Selection from command!');
const active = Position.FromVSCodePosition(selection.active);
const anchor = Position.FromVSCodePosition(selection.anchor);
this.vimState.cursorStopPosition = active;
this.vimState.cursorStartPosition = anchor;
if (e.kind === vscode.TextEditorSelectionChangeKind.Keyboard) {
if (selection.anchor.isBefore(selection.active)) {
// This is another case where we are changing our cursor so that the selection looks right
this.vimState.cursorStopPosition = active.getRight();
}
}
await this.setCurrentMode(Mode.Visual);
// Here we need our updateView to draw the selection because we want vscode to include the
// initial character, and by doing it through out updateView we make sure that any resultant
// selection change event will be ignored.
await this.updateView(this.vimState);
return;
}
}
// Here we are on the selection changed of kind 'Keyboard' or 'undefined' which is triggered
// when pressing movement keys that are not caught on the 'type' override but also when using
// commands like 'cursorMove'.

if (isVisualMode(this.vimState.currentMode)) {
/**
Expand Down
Loading