Skip to content

Commit

Permalink
fix: ensure cursor is in bounds. closes #3441
Browse files Browse the repository at this point in the history
  • Loading branch information
jpoon committed Feb 2, 2019
1 parent 088536d commit fe707b4
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/common/motion/range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export class Range {
this._stop = stop;
}

public isValid(textEditor: vscode.TextEditor) {
return this._start.isValid(textEditor) && this._stop.isValid(textEditor);
}

/**
* Create a range from a VSCode selection.
*/
Expand Down
38 changes: 24 additions & 14 deletions src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -606,25 +606,35 @@ export class ModeHandler implements vscode.Disposable {

// Ensure cursor is within bounds
if (!vimState.editor.document.isClosed && vimState.editor === vscode.window.activeTextEditor) {
for (const { stop, i } of Range.IterateRanges(vimState.allCursors)) {
if (stop.line >= TextEditor.getLineCount()) {
vimState.allCursors[i] = vimState.allCursors[i].withNewStop(
vimState.cursorPosition.getDocumentEnd(vimState.editor)
);
const cursors = new Array<Range>();
for (let { range } of Range.IterateRanges(vimState.allCursors)) {
// adjust start/stop
const documentEndPosition = vimState.cursorPosition.getDocumentEnd(vimState.editor);
const documentLineCount = TextEditor.getLineCount(vimState.editor);
if (range.start.line >= documentLineCount) {
range = range.withNewStart(documentEndPosition);
}
if (range.stop.line >= documentLineCount) {
range = range.withNewStop(documentEndPosition);
}

const currentLineLength = TextEditor.getLineAt(stop).text.length;
// adjust column
if (vimState.currentMode === ModeName.Normal) {
const currentLineLength = TextEditor.getLineAt(range.stop).text.length;
if (currentLineLength > 0) {
const lineEndPosition = range.start.getLineEnd().getLeftThroughLineBreaks(true);
if (range.start.character >= currentLineLength) {
range = range.withNewStart(lineEndPosition);
}

if (
vimState.currentMode === ModeName.Normal &&
stop.character >= currentLineLength &&
currentLineLength > 0
) {
vimState.allCursors[i] = vimState.allCursors[i].withNewStop(
stop.getLineEnd().getLeftThroughLineBreaks(true)
);
if (range.stop.character >= currentLineLength) {
range = range.withNewStop(lineEndPosition);
}
}
}
cursors.push(range);
}
vimState.allCursors = cursors;
}

// Update the current history step to have the latest cursor position
Expand Down
11 changes: 5 additions & 6 deletions src/state/vimState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,14 @@ export class VimState implements vscode.Disposable {
return this._allCursors;
}

public set allCursors(value: Range[]) {
for (const cursor of value) {
if (!cursor.start.isValid(this.editor) || !cursor.stop.isValid(this.editor)) {
this.logger.debug('invalid value for set cursor position.');
public set allCursors(cursors: Range[]) {
for (const cursor of cursors) {
if (!cursor.isValid(this.editor)) {
this.logger.warn(`invalid cursor position. ${cursor.toString()}.`);
}
}

this._allCursors = value;

this._allCursors = cursors;
this.isMultiCursor = this._allCursors.length > 1;
}

Expand Down

0 comments on commit fe707b4

Please sign in to comment.