diff --git a/src/actions/commands/actions.ts b/src/actions/commands/actions.ts index 89e988874abb..d71b5a1ad5e2 100644 --- a/src/actions/commands/actions.ts +++ b/src/actions/commands/actions.ts @@ -9,7 +9,7 @@ import { FileCommand } from './../../cmd_line/commands/file'; import { OnlyCommand } from './../../cmd_line/commands/only'; import { QuitCommand } from './../../cmd_line/commands/quit'; import { Tab, TabCommand } from './../../cmd_line/commands/tab'; -import { Position, PositionDiff } from './../../common/motion/position'; +import { Position, PositionDiff, PositionDiffType } from './../../common/motion/position'; import { Range } from './../../common/motion/range'; import { NumericString } from './../../common/number/numericString'; import { configuration } from './../../configuration/configuration'; @@ -639,7 +639,7 @@ class CommandEscReplaceMode extends BaseCommand { type: 'insertText', text: textToAdd, position: position, - diff: new PositionDiff(0, -1), + diff: new PositionDiff({ character: -1 }), }); await vimState.setCurrentMode(Mode.Normal); @@ -892,7 +892,7 @@ class CommandReplaceInReplaceMode extends BaseCommand { text: replaceState.originalChars[position.character - 1], start: position.getLeft(), end: position, - diff: new PositionDiff(0, -1), + diff: new PositionDiff({ character: -1 }), }); } @@ -904,7 +904,7 @@ class CommandReplaceInReplaceMode extends BaseCommand { text: char, start: position, end: position.getRight(), - diff: new PositionDiff(0, 1), + diff: new PositionDiff({ character: 1 }), }); } else { vimState.recordedState.transformations.push({ @@ -1498,7 +1498,7 @@ export class PutCommand extends BaseCommand { let textToAdd: string; let whereToAddText: Position; - let diff = new PositionDiff(0, 0); + let diff = new PositionDiff(); const noPrevLine = vimState.cursorStartPosition.isAtDocumentBegin(); const noNextLine = vimState.cursorStopPosition.isAtDocumentEnd(); @@ -1585,7 +1585,7 @@ export class PutCommand extends BaseCommand { register.registerMode === RegisterMode.LineWise ) { const numNewline = [...text].filter(c => c === '\n').length; - diff = PositionDiff.NewBOLDiff(-numNewline - (noNextLine ? 0 : 1)); + diff = PositionDiff.newBOLDiff(-numNewline - (noNextLine ? 0 : 1)); } else if (register.registerMode === RegisterMode.LineWise) { const check = text.match(/^\s*/); let numWhitespace = 0; @@ -1595,35 +1595,59 @@ export class PutCommand extends BaseCommand { } if (after) { - diff = PositionDiff.NewBOLDiff(-numNewlines - 1, numWhitespace); + diff = new PositionDiff({ + line: -numNewlines - 1, + character: numWhitespace, + type: PositionDiffType.ExactCharacter, + }); } else { - diff = PositionDiff.NewBOLDiff(currentLineLength > 0 ? 1 : -numNewlines, numWhitespace); + diff = new PositionDiff({ + line: currentLineLength > 0 ? 1 : -numNewlines, + character: numWhitespace, + type: PositionDiffType.ExactCharacter, + }); } } else { if (!text.includes('\n')) { if (!position.isLineEnd()) { if (register.registerMode === RegisterMode.BlockWise) { if (after) { - diff = new PositionDiff(0, -1 * text.length); + diff = new PositionDiff({ + character: -text.length, + }); } else { - diff = new PositionDiff(0, 1); + diff = new PositionDiff({ + character: 1, + }); } } else { if (after) { - diff = new PositionDiff(0, -1); + diff = new PositionDiff({ + character: -1, + }); } else { - diff = new PositionDiff(0, textToAdd.length); + diff = new PositionDiff({ + character: textToAdd.length, + }); } } } } else { if (position.isLineEnd()) { - diff = PositionDiff.NewBOLDiff(-numNewlines, position.character); + diff = new PositionDiff({ + line: -numNewlines, + character: position.character, + }); } else { if (after) { - diff = PositionDiff.NewBOLDiff(-numNewlines, position.character); + diff = new PositionDiff({ + line: -numNewlines, + character: position.character, + }); } else { - diff = new PositionDiff(0, 1); + diff = new PositionDiff({ + character: 1, + }); } } } @@ -1696,7 +1720,7 @@ export class PutCommand extends BaseCommand { result.recordedState.transformations.push({ type: 'moveCursor', - diff: new PositionDiff(-numNewlines + 1, 0), + diff: new PositionDiff({ line: -numNewlines + 1 }), cursorIndex: this.multicursorIndex, }); @@ -1745,7 +1769,7 @@ export class GPutCommand extends BaseCommand { if (vimState.effectiveRegisterMode === RegisterMode.LineWise) { result.recordedState.transformations.push({ type: 'moveCursor', - diff: PositionDiff.NewBOLDiff(addedLinesCount, 0), + diff: PositionDiff.newBOLDiff(addedLinesCount), cursorIndex: this.multicursorIndex, }); } @@ -1888,7 +1912,7 @@ export class GPutBeforeCommand extends BaseCommand { if (vimState.effectiveRegisterMode === RegisterMode.LineWise) { result.recordedState.transformations.push({ type: 'moveCursor', - diff: PositionDiff.NewBOLDiff(addedLinesCount, 0), + diff: PositionDiff.newBOLDiff(addedLinesCount), cursorIndex: this.multicursorIndex, }); } @@ -3646,18 +3670,18 @@ class ActionJoin extends BaseCommand { startLineNumber = position.line; startColumn = 0; endLineNumber = startLineNumber + count; - endColumn = TextEditor.getLineMaxColumn(endLineNumber); + endColumn = TextEditor.getLineLength(endLineNumber); } else { startLineNumber = position.line; startColumn = 0; endLineNumber = position.line; - endColumn = TextEditor.getLineMaxColumn(endLineNumber); + endColumn = TextEditor.getLineLength(endLineNumber); } } else { startLineNumber = startPosition.line; startColumn = 0; endLineNumber = position.line; - endColumn = TextEditor.getLineMaxColumn(endLineNumber); + endColumn = TextEditor.getLineLength(endLineNumber); } let trimmedLinesContent = TextEditor.getLineAt(startPosition).text; @@ -3715,10 +3739,9 @@ class ActionJoin extends BaseCommand { text: trimmedLinesContent, start: deleteStartPosition, end: deleteEndPosition, - diff: new PositionDiff( - 0, - trimmedLinesContent.length - columnDeltaOffset - position.character - ), + diff: new PositionDiff({ + character: trimmedLinesContent.length - columnDeltaOffset - position.character, + }), }); } else { vimState.recordedState.transformations.push({ @@ -3836,7 +3859,7 @@ class ActionJoinNoWhitespace extends BaseCommand { type: 'insertText', text: resultLine, position: position, - diff: new PositionDiff(0, -lineTwo.length), + diff: new PositionDiff({ character: -lineTwo.length }), }); newState.cursorStopPosition = new Position(position.line, lineOne.length); @@ -3915,7 +3938,7 @@ class ActionReplaceCharacter extends BaseCommand { vimState.recordedState.transformations.push({ type: 'tab', cursorIndex: this.multicursorIndex, - diff: new PositionDiff(0, -1), + diff: new PositionDiff({ character: -1 }), }); } else if (toReplace === '\n') { // A newline replacement always inserts exactly one newline (regardless @@ -3925,7 +3948,7 @@ class ActionReplaceCharacter extends BaseCommand { text: '\n', start: position, end: endPos, - diff: PositionDiff.NewBOLDiff(1), + diff: PositionDiff.newBOLDiff(1), }); } else { vimState.recordedState.transformations.push({ @@ -3933,7 +3956,7 @@ class ActionReplaceCharacter extends BaseCommand { text: toReplace.repeat(timesToRepeat), start: position, end: endPos, - diff: new PositionDiff(0, timesToRepeat - 1), + diff: new PositionDiff({ character: timesToRepeat - 1 }), }); } return vimState; diff --git a/src/actions/commands/insert.ts b/src/actions/commands/insert.ts index 3b4bb20f7e90..38850bbe1596 100644 --- a/src/actions/commands/insert.ts +++ b/src/actions/commands/insert.ts @@ -83,12 +83,12 @@ class CommandEscInsertMode extends BaseCommand { docChanges.push(change.textDiff); } - let positionDiff = new PositionDiff(0, 0); + let positionDiff = new PositionDiff(); // Add count amount of inserts in the case of 4i= for (let i = 0; i < vimState.recordedState.count - 1; i++) { // If this is the last transform, move cursor back one character if (i === vimState.recordedState.count - 2) { - positionDiff = new PositionDiff(0, -1); + positionDiff = new PositionDiff({ character: -1 }); } // Add a transform containing the change @@ -205,7 +205,7 @@ class CommandInsertIndentInCurrentLine extends BaseCommand { text: TextEditor.setIndentationLevel(originalText, newIndentationWidth), start: position.getLineBegin(), end: position.getLineEnd(), - diff: new PositionDiff(0, newIndentationWidth - indentationWidth), + diff: new PositionDiff({ character: newIndentationWidth - indentationWidth }), }); return vimState; diff --git a/src/actions/motion.ts b/src/actions/motion.ts index 11b3e2f7d03c..f65697226da4 100644 --- a/src/actions/motion.ts +++ b/src/actions/motion.ts @@ -1478,7 +1478,7 @@ export abstract class MoveInsideCharacter extends ExpandingSelection { return { start: startPos, stop: endPos, - diff: new PositionDiff(0, startPos === position ? 1 : 0), + diff: new PositionDiff({ character: startPos === position ? 1 : 0 }), }; } } diff --git a/src/actions/operator.ts b/src/actions/operator.ts index a9e80e16500f..5b4d2f89ca26 100644 --- a/src/actions/operator.ts +++ b/src/actions/operator.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; -import { Position, PositionDiff } from './../common/motion/position'; +import { Position, PositionDiff, PositionDiffType } from './../common/motion/position'; import { Range } from './../common/motion/range'; import { configuration } from './../configuration/configuration'; import { Mode, isVisualMode } from './../mode/mode'; @@ -183,7 +183,7 @@ export class DeleteOperator extends BaseOperator { Register.put(text, vimState, this.multicursorIndex); } - let diff = new PositionDiff(0, 0); + let diff = new PositionDiff(); let resultingPosition: Position; if (currentMode === Mode.Visual) { @@ -192,14 +192,16 @@ export class DeleteOperator extends BaseOperator { if (start.character > TextEditor.getLineAt(start).text.length) { resultingPosition = start.getLeft(); - diff = new PositionDiff(0, -1); + diff = new PositionDiff({ character: -1 }); } else { resultingPosition = start; } if (registerMode === RegisterMode.LineWise) { resultingPosition = resultingPosition.obeyStartOfLine(); - diff = PositionDiff.NewBOLDiff(0, 0, true); + diff = new PositionDiff({ + type: PositionDiffType.ObeyStartOfLine, + }); } vimState.recordedState.transformations.push({ @@ -598,7 +600,7 @@ export class ChangeOperator extends BaseOperator { // the line. We do want to run delete if it is a multiline change though ex. c} vimState.currentRegisterMode = RegisterMode.CharacterWise; if ( - Position.getLineLength(TextEditor.getLineAt(start).lineNumber) !== 0 || + TextEditor.getLineLength(TextEditor.getLineAt(start).lineNumber) !== 0 || end.line !== start.line ) { if (isLineWise) { @@ -655,7 +657,7 @@ export class ChangeOperator extends BaseOperator { vimState.recordedState.transformations.push({ type: 'reindent', cursorIndex: this.multicursorIndex, - diff: new PositionDiff(0, 1), // Handle transition from Normal to Insert modes + diff: new PositionDiff({ character: 1 }), // Handle transition from Normal to Insert modes }); } } @@ -1100,7 +1102,7 @@ class ActionVisualReflowParagraph extends BaseOperator { start: start, end: end, // Move cursor to front of line to realign the view - diff: PositionDiff.NewBOLDiff(0, 0), + diff: PositionDiff.newBOLDiff(), }); await vimState.setCurrentMode(Mode.Normal); diff --git a/src/actions/textobject.ts b/src/actions/textobject.ts index fdebadcd122d..42aabe765de5 100644 --- a/src/actions/textobject.ts +++ b/src/actions/textobject.ts @@ -564,9 +564,9 @@ abstract class IndentObjectMatch extends TextObjectMovement { // TextEditor.getLineMaxColumn throws when given line 0, which we don't // care about here since it just means this text object wouldn't work on a // single-line document. - let endCharacter; + let endCharacter: number; if (endLineNumber === TextEditor.getLineCount() - 1 || vimState.currentMode === Mode.Visual) { - endCharacter = TextEditor.getLineMaxColumn(endLineNumber); + endCharacter = TextEditor.getLineLength(endLineNumber); } else { endCharacter = 0; endLineNumber++; diff --git a/src/cmd_line/commandLine.ts b/src/cmd_line/commandLine.ts index beb85a643789..d7c17acd7bac 100644 --- a/src/cmd_line/commandLine.ts +++ b/src/cmd_line/commandLine.ts @@ -119,7 +119,7 @@ class CommandLine { }; } - public async ShowHistory(initialText: string, vimState: VimState): Promise { + public async showHistory(initialText: string): Promise { if (!vscode.window.activeTextEditor) { this._logger.debug('No active document.'); return ''; diff --git a/src/common/matching/matcher.ts b/src/common/matching/matcher.ts index e427f30e59ab..12766d0fa507 100644 --- a/src/common/matching/matcher.ts +++ b/src/common/matching/matcher.ts @@ -191,7 +191,7 @@ export class PairMatcher { let isNextMatch = false; if (charactersToMatch.includes(deleteText)) { - const matchPosition = currentPosition.add(new PositionDiff(0, 1)); + const matchPosition = currentPosition.add(new PositionDiff({ character: 1 })); matchRange = new vscode.Range(matchPosition, matchPosition.getLeftThroughLineBreaks()); isNextMatch = vscode.window.activeTextEditor!.document.getText(matchRange) === diff --git a/src/common/motion/position.ts b/src/common/motion/position.ts index 54895bfcdbfd..5616a8692157 100644 --- a/src/common/motion/position.ts +++ b/src/common/motion/position.ts @@ -1,84 +1,71 @@ import * as vscode from 'vscode'; +import * as _ from 'lodash'; import { VimState } from '../../state/vimState'; import { configuration } from './../../configuration/configuration'; import { TextEditor } from './../../textEditor'; -import * as _ from 'lodash'; import { visualBlockGetTopLeftPosition, visualBlockGetBottomRightPosition } from '../../mode/mode'; +import { clamp } from '../../util/util'; -enum PositionDiffType { +/** + * Controls how a PositionDiff affects the Position it's applied to. + */ +export enum PositionDiffType { + /** Simple line and column offset */ Offset, - BOL, + /** + * Sets the Position's column to `PositionDiff.character` + */ + ExactCharacter, + /** Brings the Position to the beginning of the line if `vim.startofline` is true */ ObeyStartOfLine, } /** - * Represents a difference between two positions. Add it to a position - * to get another position. Create it with the factory methods: - * - * - NewDiff - * - NewBOLDiff (BOL = Beginning Of Line) + * Represents a difference between two Positions. + * Add it to a Position to get another Position. */ export class PositionDiff { - private _line: number; - private _character: number; - private _type: PositionDiffType; + public readonly line: number; + public readonly character: number; + public readonly type: PositionDiffType; - constructor(line: number, character: number) { - this._line = line; - this._character = character; - this._type = PositionDiffType.Offset; - } - - /** - * Creates a new PositionDiff that always brings the cursor to the beginning - * of the line when * applied to a position. If `obeysStartOfLine` is true, - * it will go to BOL only if `vim.startofline` is true. - */ - public static NewBOLDiff(line = 0, character = 0, obeysStartOfLine = false): PositionDiff { - const result = new PositionDiff(line, character); - - result._type = obeysStartOfLine ? PositionDiffType.ObeyStartOfLine : PositionDiffType.BOL; - return result; + constructor({ line = 0, character = 0, type = PositionDiffType.Offset } = {}) { + this.line = line; + this.character = character; + this.type = type; } /** * Add this PositionDiff to another PositionDiff. */ - addDiff(other: PositionDiff) { - if (this._type !== PositionDiffType.Offset || other._type !== PositionDiffType.Offset) { + public addDiff(other: PositionDiff) { + if (this.type !== PositionDiffType.Offset || other.type !== PositionDiffType.Offset) { throw new Error("johnfn hasn't done this case yet and doesnt want to"); } - return new PositionDiff(this._line + other._line, this._character + other._character); - } - - public get type(): PositionDiffType { - return this._type; - } - - /** - * Difference in lines. - */ - public get line(): number { - return this._line; + return new PositionDiff({ + line: this.line + other.line, + character: this.character + other.character, + }); } - /** - * Difference in characters. - */ - public get character(): number { - return this._character; + public static newBOLDiff(lineOffset: number = 0) { + return new PositionDiff({ + line: lineOffset, + character: 0, + type: PositionDiffType.ExactCharacter, + }); } public toString(): string { - switch (this._type) { + switch (this.type) { case PositionDiffType.Offset: - return `[ Diff: ${this._line} ${this._character} ]`; - case PositionDiffType.BOL: - return '[ Diff: BOL ]'; + return `[ Diff: Offset ${this.line} ${this.character} ]`; + case PositionDiffType.ExactCharacter: + return `[ Diff: ExactCharacter ${this.line} ${this.character} ]`; case PositionDiffType.ObeyStartOfLine: - return '[ Diff: ObeyStartOfLine ]'; + return `[ Diff: ObeyStartOfLine ${this.line} ]`; default: throw new Error('Unknown PositionDiffType'); } @@ -118,36 +105,18 @@ export class Position extends vscode.Position { * Returns which of the 2 provided Positions comes earlier in the document. */ public static EarlierOf(p1: Position, p2: Position): Position { - if (p1.line < p2.line) { - return p1; - } - if (p1.line === p2.line && p1.character < p2.character) { - return p1; - } - - return p2; - } - - public isEarlierThan(other: Position): boolean { - if (this.line < other.line) { - return true; - } - if (this.line === other.line && this.character < other.character) { - return true; - } - - return false; + return p1.isEarlierThan(p2) ? p1 : p2; } /** * Returns which of the 2 provided Positions comes later in the document. */ public static LaterOf(p1: Position, p2: Position): Position { - if (Position.EarlierOf(p1, p2) === p1) { - return p2; - } + return p1.isEarlierThan(p2) ? p2 : p1; + } - return p1; + public isEarlierThan(other: Position): boolean { + return this.line < other.line || (this.line === other.line && this.character < other.character); } /** @@ -158,13 +127,11 @@ export class Position extends vscode.Position { start: Position, forward = true ): Iterable<{ line: string; char: string; pos: Position }> { - let lineIndex: number, charIndex: number; - if (forward) { - for (lineIndex = start.line; lineIndex < TextEditor.getLineCount(); lineIndex++) { - charIndex = lineIndex === start.line ? start.character : 0; + for (let lineIndex = start.line; lineIndex < TextEditor.getLineCount(); lineIndex++) { const line = TextEditor.getLineAt(new Position(lineIndex, 0)).text; + let charIndex = lineIndex === start.line ? start.character : 0; for (; charIndex < line.length; charIndex++) { yield { line: line, @@ -174,10 +141,10 @@ export class Position extends vscode.Position { } } } else { - for (lineIndex = start.line; lineIndex >= 0; lineIndex--) { + for (let lineIndex = start.line; lineIndex >= 0; lineIndex--) { const line = TextEditor.getLineAt(new Position(lineIndex, 0)).text; - charIndex = lineIndex === start.line ? start.character : line.length - 1; + let charIndex = lineIndex === start.line ? start.character : line.length - 1; for (; charIndex >= 0; charIndex--) { yield { line: line, @@ -316,7 +283,10 @@ export class Position extends vscode.Position { * Subtracts another position from this one, returning the difference between the two. */ public subtract(other: Position): PositionDiff { - return new PositionDiff(this.line - other.line, this.character - other.character); + return new PositionDiff({ + line: this.line - other.line, + character: this.character - other.character, + }); } /** @@ -324,38 +294,31 @@ export class Position extends vscode.Position { */ public add(diff: PositionDiff, { boundsCheck = true } = {}): Position { let resultLine = this.line + diff.line; - let resultChar = this.character; + let resultChar: number; if (diff.type === PositionDiffType.Offset) { - resultChar += diff.character; - } else if (diff.type === PositionDiffType.BOL) { + resultChar = this.character + diff.character; + } else if (diff.type === PositionDiffType.ExactCharacter) { resultChar = diff.character; } else if (diff.type === PositionDiffType.ObeyStartOfLine && configuration.startofline) { resultChar = new Position(resultLine, 0).obeyStartOfLine().character; } if (boundsCheck) { - if (resultChar < 0) { - resultChar = 0; - } - if (resultLine < 0) { - resultLine = 0; - } - // TODO: check character does not go over line's max - if (resultLine >= TextEditor.getLineCount() - 1) { - resultLine = TextEditor.getLineCount() - 1; - } + resultLine = clamp(resultLine, 0, TextEditor.getLineCount()); + resultChar = clamp(resultChar, 0, TextEditor.getLineLength(resultLine)); } return new Position(resultLine, resultChar); } public withLine(line: number): Position { + line = clamp(line, 0, TextEditor.getLineCount()); return new Position(line, this.character); } public withColumn(column: number): Position { - column = Math.min(column, Position.getLineLength(this.line)); + column = clamp(column, 0, TextEditor.getLineLength(this.line)); return new Position(this.line, column); } @@ -459,7 +422,7 @@ export class Position extends vscode.Position { public getDown(desiredColumn: number): Position { if (this.getDocumentEnd().line !== this.line) { let nextLine = this.line + 1; - let nextLineLength = Position.getLineLength(nextLine); + let nextLineLength = TextEditor.getLineLength(nextLine); return new Position(nextLine, Math.min(nextLineLength, desiredColumn)); } @@ -473,7 +436,7 @@ export class Position extends vscode.Position { public getUp(desiredColumn: number): Position { if (this.getDocumentBegin().line !== this.line) { let prevLine = this.line - 1; - let prevLineLength = Position.getLineLength(prevLine); + let prevLineLength = TextEditor.getLineLength(prevLine); return new Position(prevLine, Math.min(prevLineLength, desiredColumn)); } @@ -684,6 +647,9 @@ export class Position extends vscode.Position { return (trimWhite ? text.trim() : text) === ''; } + /** + * Returns true if the line this Position is on consists of only whitespace. + */ public isLineWhite(): boolean { return this.isLineBlank(true); } @@ -745,7 +711,7 @@ export class Position extends vscode.Position { * Returns a new position at the end of this position's line. */ public getLineEnd(): Position { - return new Position(this.line, Position.getLineLength(this.line)); + return new Position(this.line, TextEditor.getLineLength(this.line)); } /** @@ -753,7 +719,7 @@ export class Position extends vscode.Position { * invisible newline character. */ public getLineEndIncludingEOL(): Position { - return new Position(this.line, Position.getLineLength(this.line) + 1); + return new Position(this.line, TextEditor.getLineLength(this.line) + 1); } public getDocumentBegin(): Position { @@ -765,7 +731,7 @@ export class Position extends vscode.Position { * returns this position. */ public getLeftIfEOL(): Position { - if (this.character === Position.getLineLength(this.line)) { + if (this.character === TextEditor.getLineLength(this.line)) { return this.getLeft(); } else { return this; @@ -788,10 +754,9 @@ export class Position extends vscode.Position { } public getDocumentEnd(textEditor?: vscode.TextEditor): Position { - textEditor = textEditor || vscode.window.activeTextEditor; - let lineCount = TextEditor.getLineCount(textEditor); - let line = lineCount > 0 ? lineCount - 1 : 0; - let char = Position.getLineLength(line); + const lineCount = TextEditor.getLineCount(textEditor); + const line = lineCount > 0 ? lineCount - 1 : 0; + const char = TextEditor.getLineLength(line); return new Position(line, char); } @@ -807,7 +772,7 @@ export class Position extends vscode.Position { * Is this position at the end of the line? */ public isLineEnd(): boolean { - return this.character >= Position.getLineLength(this.line); + return this.character >= TextEditor.getLineLength(this.line); } public isFirstWordOfLine(): boolean { @@ -852,20 +817,17 @@ export class Position extends vscode.Position { return configuration.startofline ? this.getFirstLineNonBlankChar() : this; } - public static getLineLength(line: number): number { - return TextEditor.readLineAt(line).length; - } - - public isValid(textEditor?: vscode.TextEditor): boolean { + public isValid(textEditor: vscode.TextEditor): boolean { try { // line + // TODO: this `|| 1` seems dubious... let lineCount = TextEditor.getLineCount(textEditor) || 1; if (this.line >= lineCount) { return false; } // char - let charCount = Position.getLineLength(this.line); + let charCount = TextEditor.getLineLength(this.line); if (this.character > charCount + 1) { return false; } diff --git a/src/mode/modeHandler.ts b/src/mode/modeHandler.ts index 17e6c973a1c8..fecd302426e9 100644 --- a/src/mode/modeHandler.ts +++ b/src/mode/modeHandler.ts @@ -373,7 +373,7 @@ export class ModeHandler implements vscode.Disposable { lastAction.contentChanges = lastAction.contentChanges.concat( vimState.historyTracker.currentContentChanges.map(x => ({ textDiff: x, - positionDiff: new PositionDiff(0, 0), + positionDiff: new PositionDiff(), })) ); vimState.historyTracker.currentContentChanges = []; @@ -728,7 +728,7 @@ export class ModeHandler implements vscode.Disposable { // the newline character, which it places 1 past the last character // in the line. This is why we use > instead of >=. - if (stop.character > Position.getLineLength(stop.line)) { + if (stop.character > TextEditor.getLineLength(stop.line)) { vimState.cursorStopPosition = stop.getLineEnd(); } } @@ -913,7 +913,7 @@ export class ModeHandler implements vscode.Disposable { break; case 'showCommandHistory': - let cmd = await commandLine.ShowHistory(vimState.currentCommandlineText, this.vimState); + let cmd = await commandLine.showHistory(vimState.currentCommandlineText); if (cmd && cmd.length !== 0) { await commandLine.Run(cmd, this.vimState); this.updateView(this.vimState); diff --git a/src/neovim/neovim.ts b/src/neovim/neovim.ts index db0e04ab4735..78e53759157a 100644 --- a/src/neovim/neovim.ts +++ b/src/neovim/neovim.ts @@ -154,17 +154,14 @@ export class NeovimWrapper implements vscode.Disposable { const fixedLines = process.platform === 'win32' ? lines.map((line, index) => line.replace(/\r$/, '')) : lines; + const lineCount = TextEditor.getLineCount(); + await TextEditor.replace( - new vscode.Range( - 0, - 0, - TextEditor.getLineCount() - 1, - TextEditor.getLineMaxColumn(TextEditor.getLineCount() - 1) - ), + new vscode.Range(0, 0, lineCount - 1, TextEditor.getLineLength(lineCount - 1)), fixedLines.join('\n') ); - this.logger.debug(`${lines.length} lines in nvim. ${TextEditor.getLineCount()} in editor.`); + this.logger.debug(`${lines.length} lines in nvim. ${lineCount} in editor.`); let [row, character] = ((await this.nvim.callFunction('getpos', ['.'])) as Array).slice( 1, diff --git a/src/state/searchState.ts b/src/state/searchState.ts index 4b3c34980842..fd325f698dd4 100644 --- a/src/state/searchState.ts +++ b/src/state/searchState.ts @@ -258,7 +258,7 @@ export class SearchState { let pos = start; if (this.offset) { if (this.offset.type === 'line') { - pos = start.add(PositionDiff.NewBOLDiff(this.offset.num)); + pos = start.add(PositionDiff.newBOLDiff(this.offset.num)); } else if (this.offset.type === 'beginning') { pos = start.getOffsetThroughLineBreaks(this.offset.num); } else if (this.offset.type === 'end') { diff --git a/src/textEditor.ts b/src/textEditor.ts index 923e3aef8476..28fcf39f5c3e 100644 --- a/src/textEditor.ts +++ b/src/textEditor.ts @@ -106,8 +106,16 @@ export class TextEditor { } static getLineCount(textEditor?: vscode.TextEditor): number { - textEditor = textEditor || vscode.window.activeTextEditor; - return textEditor ? textEditor.document.lineCount : -1; + textEditor = textEditor ?? vscode.window.activeTextEditor; + return textEditor?.document.lineCount ?? -1; + } + + public static getLineLength(line: number): number { + if (line < 0 || line > TextEditor.getLineCount()) { + throw new Error(`getLineLength() called with out-of-bounds line ${line}`); + } + + return TextEditor.readLineAt(line).length; } static getLineAt(position: vscode.Position): vscode.TextLine { @@ -120,14 +128,6 @@ export class TextEditor { return line.text[position.character]; } - static getLineMaxColumn(lineNumber: number): number { - if (lineNumber < 0 || lineNumber > TextEditor.getLineCount()) { - throw new Error('Illegal value ' + lineNumber + ' for `lineNumber`'); - } - - return TextEditor.readLineAt(lineNumber).length; - } - static getSelection(): vscode.Range { return vscode.window.activeTextEditor!.selection; }