diff --git a/README.md b/README.md index 41afb36ab84..bab826ddab6 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Status | Key | Description | | | to column N (default: 1) | f | to the Nth occurrence of to the right | F | to the Nth occurrence of to the left - | t |till before the Nth occurrence of to the right + | t | till before the Nth occurrence of to the right | T | till before the Nth occurrence of to the left | ; | repeat the last "f", "F", "t", or "T" N times | , | repeat the last "f", "F", "t", or "T" N times in opposite direction @@ -67,18 +67,21 @@ Status | Key | Description :white_check_mark: | G | goto last line, on the first non-blank character :white_check_mark: | gg | goto frst line, on the firstnon-blank character | % | goto line N percentage down in the file. N must be given, otherwise it is the % command. +matching brace | % | jump to matching brace, C-style comment, C/C++ preprocessor conditional | gk | up N screen lines (differs from "k" when line wraps) | gj | down N screen lines (differs from "j" when line wraps) +:white_check_mark: | CTRL-F | page down +:white_check_mark: | CTRL-B | page up #### Word Motions Status | Key | Description ------------------- | ------------------------- | ------------------------- :white_check_mark: | w | words forward - | W | N blank-separated WORDS forward +:white_check_mark: | W | N blank-separated WORDS forward :white_check_mark: | e | forward to the end of the word | E | forward to the end of the Nth blank-separated WORD :white_check_mark: | b | words backward - | B | N blank-separated WORDS backward +:white_check_mark: | B | N blank-separated WORDS backward | ge | backward to the end of the Nth word | gE | backward to the end of the Nth blank-separated WORD @@ -97,7 +100,7 @@ Status | Key | Description ------------------- | ------------------------- | ------------------------- :white_check_mark: | x | delete characters under and after the cursor | | delete N characters under and after the cursor - | X | delete N characters before the cursor +:white_check_mark: | X | delete N characters before the cursor dw, db | d{motion} | delete the text that is moved over with {motion} | {visual}d | delete the highlighted text :white_check_mark: | dd | delete N lines diff --git a/src/motion/position.ts b/src/motion/position.ts index 6bee47b80d3..88fcb56998b 100644 --- a/src/motion/position.ts +++ b/src/motion/position.ts @@ -29,14 +29,6 @@ export class Position extends vscode.Position { this._nonBigWordCharRegex = this.makeWordRegex(Position.NonBigWordCharacters); } - private makeWordRegex(characterSet: string) : RegExp { - let escaped = characterSet && _.escapeRegExp(characterSet); - let segments = ["(^[\t ]*$)"]; - segments.push(`([^\\s${escaped}]+)`); - segments.push(`[${escaped}]+`); - return new RegExp(segments.join("|"), "g"); - } - public setLocation(line: number, character: number) : Position { let position = new Position(line, character, this.positionOptions); return position; @@ -86,44 +78,6 @@ export class Position extends vscode.Position { return this; } - private getWordLeftWithRegex(regex: RegExp) : Position { - var workingPosition = new Position(this.line, this.character, this.positionOptions); - var currentLine = TextEditor.getLineAt(this); - var currentCharacter = this.character; - - if (!TextEditor.isFirstLine(this) && this.character <= currentLine.firstNonWhitespaceCharacterIndex) { - // perform search from very end of previous line (after last character) - workingPosition = new Position(this.line - 1, this.character, this.positionOptions); - currentLine = TextEditor.getLineAt(workingPosition); - currentCharacter = workingPosition.getLineEnd().character + 1; - } - - let positions = []; - - regex.lastIndex = 0; - while (true) { - let result = regex.exec(currentLine.text); - if (result === null) { - break; - } - positions.push(result.index); - } - - for (var index = 0; index < positions.length; index++) { - let position = positions[positions.length - 1 - index]; - if (currentCharacter > position) { - return new Position(workingPosition.line, position, workingPosition.positionOptions); - } - } - - if (this.line === 0) { - return this.getLineBegin(); - } else { - let prevLine = new Position(this.line - 1, 0, this.positionOptions); - return prevLine.getLineEnd(); - } - } - public getWordLeft() : Position { return this.getWordLeftWithRegex(this._nonWordCharRegex); } @@ -132,41 +86,6 @@ export class Position extends vscode.Position { return this.getWordLeftWithRegex(this._nonBigWordCharRegex); } - private getWordRightWithRegex(regex: RegExp) : Position { - if (!TextEditor.isLastLine(this) && this.character >= this.getLineEnd().character) { - // go to next line - let line = TextEditor.getLineAt(this.translate(1)); - return new Position(line.lineNumber, line.firstNonWhitespaceCharacterIndex, this.positionOptions); - } - - let currentLine = TextEditor.getLineAt(this); - let positions = []; - - regex.lastIndex = 0; - while (true) { - let result = regex.exec(currentLine.text); - if (result === null) { - break; - } - positions.push(result.index); - } - - for (var index = 0; index < positions.length; index++) { - let position = positions[index]; - if (this.character < position) { - return new Position(this.line, position, this.positionOptions); - } - } - - if (this.line === this.getDocumentEnd().line) { - return this.getLineEnd(); - } else { - // go to next line - let line = TextEditor.getLineAt(this.translate(1)); - return new Position(line.lineNumber, line.firstNonWhitespaceCharacterIndex, this.positionOptions); - } - } - public getWordRight() : Position { return this.getWordRightWithRegex(this._nonWordCharRegex); } @@ -311,4 +230,85 @@ export class Position extends vscode.Position { throw new Error("Unhandled PositionOptions: " + options); } } + + private makeWordRegex(characterSet: string) : RegExp { + let escaped = characterSet && _.escapeRegExp(characterSet); + let segments = ["(^[\t ]*$)"]; + segments.push(`([^\\s${escaped}]+)`); + segments.push(`[${escaped}]+`); + return new RegExp(segments.join("|"), "g"); + } + + private getWordLeftWithRegex(regex: RegExp) : Position { + var workingPosition = new Position(this.line, this.character, this.positionOptions); + var currentLine = TextEditor.getLineAt(this); + var currentCharacter = this.character; + + if (!TextEditor.isFirstLine(this) && this.character <= currentLine.firstNonWhitespaceCharacterIndex) { + // perform search from very end of previous line (after last character) + workingPosition = new Position(this.line - 1, this.character, this.positionOptions); + currentLine = TextEditor.getLineAt(workingPosition); + currentCharacter = workingPosition.getLineEnd().character + 1; + } + + let positions = []; + + regex.lastIndex = 0; + while (true) { + let result = regex.exec(currentLine.text); + if (result === null) { + break; + } + positions.push(result.index); + } + + for (var index = 0; index < positions.length; index++) { + let position = positions[positions.length - 1 - index]; + if (currentCharacter > position) { + return new Position(workingPosition.line, position, workingPosition.positionOptions); + } + } + + if (this.line === 0) { + return this.getLineBegin(); + } else { + let prevLine = new Position(this.line - 1, 0, this.positionOptions); + return prevLine.getLineEnd(); + } + } + + private getWordRightWithRegex(regex: RegExp) : Position { + if (!TextEditor.isLastLine(this) && this.character >= this.getLineEnd().character) { + // go to next line + let line = TextEditor.getLineAt(this.translate(1)); + return new Position(line.lineNumber, line.firstNonWhitespaceCharacterIndex, this.positionOptions); + } + + let currentLine = TextEditor.getLineAt(this); + let positions = []; + + regex.lastIndex = 0; + while (true) { + let result = regex.exec(currentLine.text); + if (result === null) { + break; + } + positions.push(result.index); + } + + for (var index = 0; index < positions.length; index++) { + let position = positions[index]; + if (this.character < position) { + return new Position(this.line, position, this.positionOptions); + } + } + + if (this.line === this.getDocumentEnd().line) { + return this.getLineEnd(); + } else { + // go to next line + let line = TextEditor.getLineAt(this.translate(1)); + return new Position(line.lineNumber, line.firstNonWhitespaceCharacterIndex, this.positionOptions); + } + } } \ No newline at end of file