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

Fix off by one error in visual mode #1862

Merged
merged 19 commits into from
Jun 24, 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
5 changes: 0 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,6 @@
"description": "Uses a hack to move around folds properly",
"default": false
},
"vim.disableAnnoyingGcMessage": {
"type": "boolean",
"description": "Get rid of that annoying pop up that shows up everytime you type gc or gb",
"default": false
},
"vim.enableNeovim": {
"type": "boolean",
"description": "Use neovim on backend. (only works for Ex commands right now). You should restart VScode after enable/disabling this for the changes to take effect. NOTE: Neovim must be installed (v0.2.0) and neovimPath must be set the executable in order for this setting to work. Otherwise, vscodevim will crash.",
Expand Down
19 changes: 4 additions & 15 deletions src/actions/commands/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ function searchCurrentWord(position: Position, vimState: VimState, direction: Se

function searchCurrentSelection (vimState: VimState, direction: SearchDirection) {
const selection = TextEditor.getSelection();
const end = new Position(selection.end.line, selection.end.character + 1);
const end = new Position(selection.end.line, selection.end.character);
const currentSelection = TextEditor.getText(selection.with(selection.start, end));

// Go back to Normal mode, otherwise the selection grows to the next match.
Expand Down Expand Up @@ -1364,7 +1364,7 @@ export class PutCommandVisual extends BaseCommand {
[start, end] = [end, start];
}

// If the to be inserted text is linewise we have a seperate logik delete the
// If the to be inserted text is linewise we have a seperate logic delete the
// selection first than insert
let register = await Register.get(vimState);
if (register.registerMode === RegisterMode.LineWise) {
Expand Down Expand Up @@ -1830,7 +1830,7 @@ class CommandReselectVisual extends BaseCommand {
if (vimState.lastVisualSelectionEnd.line <= (TextEditor.getLineCount() - 1)) {
vimState.currentMode = vimState.lastVisualMode;
vimState.cursorStartPosition = vimState.lastVisualSelectionStart;
vimState.cursorPosition = vimState.lastVisualSelectionEnd;
vimState.cursorPosition = vimState.lastVisualSelectionEnd.getLeft();
}

}
Expand Down Expand Up @@ -3129,23 +3129,12 @@ class ActionOverrideCmdD extends BaseCommand {
runsOnceForEachCountPrefix = true;

public async exec(position: Position, vimState: VimState): Promise<VimState> {
if (!Configuration.disableAnnoyingGcMessage) {
vscode.window.showInformationMessage("gc is now commentOperator. gb is now 'add new cursor'", "Never show again").then(
(result) => {
if (result === "Never show again") {
vscode.workspace.getConfiguration("vim").update("disableAnnoyingGcMessage", true, true);
Configuration.disableAnnoyingGcMessage = true;
}
});
}
await vscode.commands.executeCommand('editor.action.addSelectionToNextFindMatch');
vimState.allCursors = await allowVSCodeToPropagateCursorUpdatesAndReturnThem();

// If this is the first cursor, select 1 character less
// so that only the word is selected, no extra character
if (vimState.allCursors.length === 1) {
vimState.allCursors[0] = vimState.allCursors[0].withNewStop(vimState.allCursors[0].stop.getLeft());
}
vimState.allCursors = vimState.allCursors.map(x => x.withNewStop(x.stop.getLeft()));

vimState.currentMode = ModeName.Visual;

Expand Down
17 changes: 2 additions & 15 deletions src/actions/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,13 @@ export class YankOperator extends BaseOperator {

const originalMode = vimState.currentMode;

if (start.compareTo(end) <= 0) {
if (start.isEarlierThan(end)) {
end = new Position(end.line, end.character + 1);
} else {
const tmp = start;
start = end;
end = tmp;
[start, end] = [end, start];

end = new Position(end.line, end.character + 1);
}

if (vimState.currentRegisterMode === RegisterMode.LineWise) {
start = start.getLineBegin();
end = end.getLineEnd();
Expand Down Expand Up @@ -611,16 +608,6 @@ export class CommentOperator extends BaseOperator {
public modes = [ModeName.Normal, ModeName.Visual, ModeName.VisualLine];

public async run(vimState: VimState, start: Position, end: Position): Promise<VimState> {
if (!Configuration.disableAnnoyingGcMessage) {
vscode.window.showInformationMessage("gc is now commentOperator. gb is now 'add new cursor'", "Never show again").then(
(result) => {
if (result === "Never show again") {
vscode.workspace.getConfiguration("vim").update("disableAnnoyingGcMessage", true, true);
Configuration.disableAnnoyingGcMessage = true;
}
});
}

vimState.editor.selection = new vscode.Selection(start.getLineBegin(), end.getLineEnd());
await vscode.commands.executeCommand("editor.action.commentLine");

Expand Down
5 changes: 0 additions & 5 deletions src/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,6 @@ class ConfigurationClass {
* Uses a hack to fix moving around folds.
*/
foldfix = false;
/**
* In a recent release, gc and gb have been swapped. An error message
* shows everytime you press one of them. This flag disables that.
*/
disableAnnoyingGcMessage = false;

enableNeovim = true;

Expand Down
1 change: 1 addition & 0 deletions src/mode/mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum ModeName {
export enum VSCodeVimCursorType {
Block,
Line,
LineThin,
Underline,
TextDecoration,
Native
Expand Down
54 changes: 40 additions & 14 deletions src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,7 @@ export class ModeHandler implements vscode.Disposable {

// start visual mode?


if (selection.anchor.line === selection.active.line
&& selection.anchor.character >= newPosition.getLineEnd().character - 1
&& selection.active.character >= newPosition.getLineEnd().character - 1) {
Expand All @@ -731,14 +732,11 @@ export class ModeHandler implements vscode.Disposable {
this._vimState.lastClickWasPastEol = false;
}

if (!this._vimState.getModeObject(this).isVisualMode &&
this._vimState.getModeObject(this).name !== ModeName.Insert) {
if (!this._vimState.getModeObject(this).isVisualMode) {
this._vimState.currentMode = ModeName.Visual;
this.setCurrentModeByName(this._vimState);

// double click mouse selection causes an extra character to be selected so take one less character
this._vimState.cursorPosition = this._vimState.cursorPosition.getLeft();
toDraw = true;
}
} else {
if (this._vimState.currentMode !== ModeName.Insert) {
Expand Down Expand Up @@ -948,6 +946,11 @@ export class ModeHandler implements vscode.Disposable {
}
*/

if (vimState.currentMode === ModeName.Visual) {
vimState.allCursors =
vimState.allCursors.map(
x => x.start.isEarlierThan(x.stop) ? x.withNewStop(x.stop.getLeftThroughLineBreaks(true)) : x);
}
if (action instanceof BaseMovement) {
({ vimState, recordedState } = await this.executeMovement(vimState, action));
ranAction = true;
Expand Down Expand Up @@ -992,6 +995,13 @@ export class ModeHandler implements vscode.Disposable {
ranAction = true;
}

if (vimState.currentMode === ModeName.Visual) {
vimState.allCursors =
vimState.allCursors.map(
x => x.start.isEarlierThan(x.stop) ?
x.withNewStop(x.stop.isLineEnd() ? x.stop.getRightThroughLineBreaks() : x.stop.getRight())
: x);
}
// And then we have to do it again because an operator could
// have changed it as well. (TODO: do you even decomposition bro)

Expand Down Expand Up @@ -1082,15 +1092,15 @@ export class ModeHandler implements vscode.Disposable {
vimState.allCursors[i] = vimState.allCursors[i].withNewStop(
vimState.cursorPosition.getDocumentEnd()
);
}
}

const currentLineLength = TextEditor.getLineAt(stop).text.length;

if (vimState.currentMode === ModeName.Normal &&
stop.character >= currentLineLength && currentLineLength > 0) {

vimState.allCursors[i] = vimState.allCursors[i].withNewStop(
stop.getLineEnd().getLeft()
stop.getLineEnd().getLeftThroughLineBreaks(true)
);
}
}
Expand Down Expand Up @@ -1153,7 +1163,7 @@ export class ModeHandler implements vscode.Disposable {
* Action definitions without having to think about multiple
* cursors in almost all cases.
*/
const cursorPosition = vimState.allCursors[i].stop;
let cursorPosition = vimState.allCursors[i].stop;
const old = vimState.cursorPosition;

vimState.cursorPosition = cursorPosition;
Expand All @@ -1165,7 +1175,6 @@ export class ModeHandler implements vscode.Disposable {

if (!vimState.getModeObject(this).isVisualMode &&
!vimState.recordedState.operator) {

vimState.allCursors[i] = vimState.allCursors[i].withNewStart(result);
}
} else if (isIMovement(result)) {
Expand Down Expand Up @@ -1466,7 +1475,11 @@ export class ModeHandler implements vscode.Disposable {
}
}

const selections = this._vimState.editor.selections;
const selections = this._vimState.editor.selections.map(x => {
let y = Range.FromVSCodeSelection(x);
y = y.start.isEarlierThan(y.stop) ? y.withNewStop(y.stop.getLeftThroughLineBreaks(true)) : y;
return new vscode.Selection(new vscode.Position(y.start.line, y.start.character), new vscode.Position(y.stop.line, y.stop.character));
});
const firstTransformation = transformations[0];
const manuallySetCursorPositions = ((firstTransformation.type === "deleteRange" ||
firstTransformation.type === "replaceText" || firstTransformation.type === "insertText")
Expand Down Expand Up @@ -1626,7 +1639,7 @@ export class ModeHandler implements vscode.Disposable {
*/

if (start.compareTo(stop) > 0) {
start = start.getRight();
start = start.getRightThroughLineBreaks();
}

selections = [ new vscode.Selection(start, stop) ];
Expand Down Expand Up @@ -1715,10 +1728,13 @@ export class ModeHandler implements vscode.Disposable {
// Use native cursor if possible. Default to Block.
let cursorStyle = vscode.TextEditorCursorStyle.Block;
switch (this.currentMode.cursorType) {
case VSCodeVimCursorType.TextDecoration:
case VSCodeVimCursorType.Line:
cursorStyle = vscode.TextEditorCursorStyle.Line;
break;
case VSCodeVimCursorType.TextDecoration:
case VSCodeVimCursorType.LineThin:
cursorStyle = vscode.TextEditorCursorStyle.LineThin;
break;
case VSCodeVimCursorType.Underline:
cursorStyle = vscode.TextEditorCursorStyle.Underline;
break;
Expand All @@ -1736,9 +1752,18 @@ export class ModeHandler implements vscode.Disposable {

// Fake block cursor with text decoration. Unfortunately we can't have a cursor
// in the middle of a selection natively, which is what we need for Visual Mode.

for (const { stop: cursorStop } of vimState.allCursors) {
cursorRange.push(new vscode.Range(cursorStop, cursorStop.getRight()));
if (this.currentModeName === ModeName.Visual) {
for (const { start: cursorStart, stop: cursorStop } of vimState.allCursors) {
if (cursorStart.isEarlierThan(cursorStop)) {
cursorRange.push(new vscode.Range(cursorStop.getLeft(), cursorStop));
} else {
cursorRange.push(new vscode.Range(cursorStop, cursorStop.getRight()));
}
}
} else {
for (const { stop: cursorStop } of vimState.allCursors) {
cursorRange.push(new vscode.Range(cursorStop, cursorStop.getRight()));
}
}
}

Expand Down Expand Up @@ -1893,6 +1918,7 @@ export class ModeHandler implements vscode.Disposable {
}

dispose() {
this._vimState.nvim.quit();
for (const disposable of this._toBeDisposed) {
disposable.dispose();
}
Expand Down
2 changes: 1 addition & 1 deletion src/mode/modeInsert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class InsertMode extends Mode {
public text = "Insert Mode";
public cursorType = VSCodeVimCursorType.Native;

constructor() {
constructor() {
super(ModeName.Insert);
}
}
2 changes: 1 addition & 1 deletion src/mode/modeVisual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { VSCodeVimCursorType } from './mode';

export class VisualMode extends Mode {
public text = "Visual Mode";
public cursorType = VSCodeVimCursorType.Block;
public cursorType = VSCodeVimCursorType.TextDecoration;
public isVisualMode = true;

constructor() {
Expand Down
2 changes: 1 addition & 1 deletion test/mode/modeVisual.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ suite("Mode Visual", () => {

// The input cursor comes BEFORE the block cursor. Try it out, this
// is how Vim works.
assert.equal(sel.end.character, 5);
assert.equal(sel.end.character, 6);
assert.equal(sel.end.line, 0);
});

Expand Down
2 changes: 1 addition & 1 deletion test/mode/modeVisualLine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ suite("Mode Visual", () => {

// The input cursor comes BEFORE the block cursor. Try it out, this
// is how Vim works.
assert.equal(sel.end.character, 5);
assert.equal(sel.end.character, 6);
assert.equal(sel.end.line, 0);
});

Expand Down