| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import * as strings from '../../../base/common/strings.js';
- import { SingleCursorState } from '../cursorCommon.js';
- import { DeleteOperations } from './cursorDeleteOperations.js';
- import { getMapForWordSeparators } from '../core/wordCharacterClassifier.js';
- import { Position } from '../core/position.js';
- import { Range } from '../core/range.js';
- export class WordOperations {
- static _createWord(lineContent, wordType, nextCharClass, start, end) {
- // console.log('WORD ==> ' + start + ' => ' + end + ':::: <<<' + lineContent.substring(start, end) + '>>>');
- return { start: start, end: end, wordType: wordType, nextCharClass: nextCharClass };
- }
- static _findPreviousWordOnLine(wordSeparators, model, position) {
- const lineContent = model.getLineContent(position.lineNumber);
- return this._doFindPreviousWordOnLine(lineContent, wordSeparators, position);
- }
- static _doFindPreviousWordOnLine(lineContent, wordSeparators, position) {
- let wordType = 0 /* WordType.None */;
- for (let chIndex = position.column - 2; chIndex >= 0; chIndex--) {
- const chCode = lineContent.charCodeAt(chIndex);
- const chClass = wordSeparators.get(chCode);
- if (chClass === 0 /* WordCharacterClass.Regular */) {
- if (wordType === 2 /* WordType.Separator */) {
- return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
- }
- wordType = 1 /* WordType.Regular */;
- }
- else if (chClass === 2 /* WordCharacterClass.WordSeparator */) {
- if (wordType === 1 /* WordType.Regular */) {
- return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
- }
- wordType = 2 /* WordType.Separator */;
- }
- else if (chClass === 1 /* WordCharacterClass.Whitespace */) {
- if (wordType !== 0 /* WordType.None */) {
- return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
- }
- }
- }
- if (wordType !== 0 /* WordType.None */) {
- return this._createWord(lineContent, wordType, 1 /* WordCharacterClass.Whitespace */, 0, this._findEndOfWord(lineContent, wordSeparators, wordType, 0));
- }
- return null;
- }
- static _findEndOfWord(lineContent, wordSeparators, wordType, startIndex) {
- const len = lineContent.length;
- for (let chIndex = startIndex; chIndex < len; chIndex++) {
- const chCode = lineContent.charCodeAt(chIndex);
- const chClass = wordSeparators.get(chCode);
- if (chClass === 1 /* WordCharacterClass.Whitespace */) {
- return chIndex;
- }
- if (wordType === 1 /* WordType.Regular */ && chClass === 2 /* WordCharacterClass.WordSeparator */) {
- return chIndex;
- }
- if (wordType === 2 /* WordType.Separator */ && chClass === 0 /* WordCharacterClass.Regular */) {
- return chIndex;
- }
- }
- return len;
- }
- static _findNextWordOnLine(wordSeparators, model, position) {
- const lineContent = model.getLineContent(position.lineNumber);
- return this._doFindNextWordOnLine(lineContent, wordSeparators, position);
- }
- static _doFindNextWordOnLine(lineContent, wordSeparators, position) {
- let wordType = 0 /* WordType.None */;
- const len = lineContent.length;
- for (let chIndex = position.column - 1; chIndex < len; chIndex++) {
- const chCode = lineContent.charCodeAt(chIndex);
- const chClass = wordSeparators.get(chCode);
- if (chClass === 0 /* WordCharacterClass.Regular */) {
- if (wordType === 2 /* WordType.Separator */) {
- return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
- }
- wordType = 1 /* WordType.Regular */;
- }
- else if (chClass === 2 /* WordCharacterClass.WordSeparator */) {
- if (wordType === 1 /* WordType.Regular */) {
- return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
- }
- wordType = 2 /* WordType.Separator */;
- }
- else if (chClass === 1 /* WordCharacterClass.Whitespace */) {
- if (wordType !== 0 /* WordType.None */) {
- return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
- }
- }
- }
- if (wordType !== 0 /* WordType.None */) {
- return this._createWord(lineContent, wordType, 1 /* WordCharacterClass.Whitespace */, this._findStartOfWord(lineContent, wordSeparators, wordType, len - 1), len);
- }
- return null;
- }
- static _findStartOfWord(lineContent, wordSeparators, wordType, startIndex) {
- for (let chIndex = startIndex; chIndex >= 0; chIndex--) {
- const chCode = lineContent.charCodeAt(chIndex);
- const chClass = wordSeparators.get(chCode);
- if (chClass === 1 /* WordCharacterClass.Whitespace */) {
- return chIndex + 1;
- }
- if (wordType === 1 /* WordType.Regular */ && chClass === 2 /* WordCharacterClass.WordSeparator */) {
- return chIndex + 1;
- }
- if (wordType === 2 /* WordType.Separator */ && chClass === 0 /* WordCharacterClass.Regular */) {
- return chIndex + 1;
- }
- }
- return 0;
- }
- static moveWordLeft(wordSeparators, model, position, wordNavigationType) {
- let lineNumber = position.lineNumber;
- let column = position.column;
- if (column === 1) {
- if (lineNumber > 1) {
- lineNumber = lineNumber - 1;
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- let prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, column));
- if (wordNavigationType === 0 /* WordNavigationType.WordStart */) {
- return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
- }
- if (wordNavigationType === 1 /* WordNavigationType.WordStartFast */) {
- if (prevWordOnLine
- && prevWordOnLine.wordType === 2 /* WordType.Separator */
- && prevWordOnLine.end - prevWordOnLine.start === 1
- && prevWordOnLine.nextCharClass === 0 /* WordCharacterClass.Regular */) {
- // Skip over a word made up of one single separator and followed by a regular character
- prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1));
- }
- return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
- }
- if (wordNavigationType === 3 /* WordNavigationType.WordAccessibility */) {
- while (prevWordOnLine
- && prevWordOnLine.wordType === 2 /* WordType.Separator */) {
- // Skip over words made up of only separators
- prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1));
- }
- return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
- }
- // We are stopping at the ending of words
- if (prevWordOnLine && column <= prevWordOnLine.end + 1) {
- prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1));
- }
- return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.end + 1 : 1);
- }
- static _moveWordPartLeft(model, position) {
- const lineNumber = position.lineNumber;
- const maxColumn = model.getLineMaxColumn(lineNumber);
- if (position.column === 1) {
- return (lineNumber > 1 ? new Position(lineNumber - 1, model.getLineMaxColumn(lineNumber - 1)) : position);
- }
- const lineContent = model.getLineContent(lineNumber);
- for (let column = position.column - 1; column > 1; column--) {
- const left = lineContent.charCodeAt(column - 2);
- const right = lineContent.charCodeAt(column - 1);
- if (left === 95 /* CharCode.Underline */ && right !== 95 /* CharCode.Underline */) {
- // snake_case_variables
- return new Position(lineNumber, column);
- }
- if ((strings.isLowerAsciiLetter(left) || strings.isAsciiDigit(left)) && strings.isUpperAsciiLetter(right)) {
- // camelCaseVariables
- return new Position(lineNumber, column);
- }
- if (strings.isUpperAsciiLetter(left) && strings.isUpperAsciiLetter(right)) {
- // thisIsACamelCaseWithOneLetterWords
- if (column + 1 < maxColumn) {
- const rightRight = lineContent.charCodeAt(column);
- if (strings.isLowerAsciiLetter(rightRight) || strings.isAsciiDigit(rightRight)) {
- return new Position(lineNumber, column);
- }
- }
- }
- }
- return new Position(lineNumber, 1);
- }
- static moveWordRight(wordSeparators, model, position, wordNavigationType) {
- let lineNumber = position.lineNumber;
- let column = position.column;
- let movedDown = false;
- if (column === model.getLineMaxColumn(lineNumber)) {
- if (lineNumber < model.getLineCount()) {
- movedDown = true;
- lineNumber = lineNumber + 1;
- column = 1;
- }
- }
- let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, column));
- if (wordNavigationType === 2 /* WordNavigationType.WordEnd */) {
- if (nextWordOnLine && nextWordOnLine.wordType === 2 /* WordType.Separator */) {
- if (nextWordOnLine.end - nextWordOnLine.start === 1 && nextWordOnLine.nextCharClass === 0 /* WordCharacterClass.Regular */) {
- // Skip over a word made up of one single separator and followed by a regular character
- nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
- }
- }
- if (nextWordOnLine) {
- column = nextWordOnLine.end + 1;
- }
- else {
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- else if (wordNavigationType === 3 /* WordNavigationType.WordAccessibility */) {
- if (movedDown) {
- // If we move to the next line, pretend that the cursor is right before the first character.
- // This is needed when the first word starts right at the first character - and in order not to miss it,
- // we need to start before.
- column = 0;
- }
- while (nextWordOnLine
- && (nextWordOnLine.wordType === 2 /* WordType.Separator */
- || nextWordOnLine.start + 1 <= column)) {
- // Skip over a word made up of one single separator
- // Also skip over word if it begins before current cursor position to ascertain we're moving forward at least 1 character.
- nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
- }
- if (nextWordOnLine) {
- column = nextWordOnLine.start + 1;
- }
- else {
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- else {
- if (nextWordOnLine && !movedDown && column >= nextWordOnLine.start + 1) {
- nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
- }
- if (nextWordOnLine) {
- column = nextWordOnLine.start + 1;
- }
- else {
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- return new Position(lineNumber, column);
- }
- static _moveWordPartRight(model, position) {
- const lineNumber = position.lineNumber;
- const maxColumn = model.getLineMaxColumn(lineNumber);
- if (position.column === maxColumn) {
- return (lineNumber < model.getLineCount() ? new Position(lineNumber + 1, 1) : position);
- }
- const lineContent = model.getLineContent(lineNumber);
- for (let column = position.column + 1; column < maxColumn; column++) {
- const left = lineContent.charCodeAt(column - 2);
- const right = lineContent.charCodeAt(column - 1);
- if (left !== 95 /* CharCode.Underline */ && right === 95 /* CharCode.Underline */) {
- // snake_case_variables
- return new Position(lineNumber, column);
- }
- if ((strings.isLowerAsciiLetter(left) || strings.isAsciiDigit(left)) && strings.isUpperAsciiLetter(right)) {
- // camelCaseVariables
- return new Position(lineNumber, column);
- }
- if (strings.isUpperAsciiLetter(left) && strings.isUpperAsciiLetter(right)) {
- // thisIsACamelCaseWithOneLetterWords
- if (column + 1 < maxColumn) {
- const rightRight = lineContent.charCodeAt(column);
- if (strings.isLowerAsciiLetter(rightRight) || strings.isAsciiDigit(rightRight)) {
- return new Position(lineNumber, column);
- }
- }
- }
- }
- return new Position(lineNumber, maxColumn);
- }
- static _deleteWordLeftWhitespace(model, position) {
- const lineContent = model.getLineContent(position.lineNumber);
- const startIndex = position.column - 2;
- const lastNonWhitespace = strings.lastNonWhitespaceIndex(lineContent, startIndex);
- if (lastNonWhitespace + 1 < startIndex) {
- return new Range(position.lineNumber, lastNonWhitespace + 2, position.lineNumber, position.column);
- }
- return null;
- }
- static deleteWordLeft(ctx, wordNavigationType) {
- const wordSeparators = ctx.wordSeparators;
- const model = ctx.model;
- const selection = ctx.selection;
- const whitespaceHeuristics = ctx.whitespaceHeuristics;
- if (!selection.isEmpty()) {
- return selection;
- }
- if (DeleteOperations.isAutoClosingPairDelete(ctx.autoClosingDelete, ctx.autoClosingBrackets, ctx.autoClosingQuotes, ctx.autoClosingPairs.autoClosingPairsOpenByEnd, ctx.model, [ctx.selection], ctx.autoClosedCharacters)) {
- const position = ctx.selection.getPosition();
- return new Range(position.lineNumber, position.column - 1, position.lineNumber, position.column + 1);
- }
- const position = new Position(selection.positionLineNumber, selection.positionColumn);
- let lineNumber = position.lineNumber;
- let column = position.column;
- if (lineNumber === 1 && column === 1) {
- // Ignore deleting at beginning of file
- return null;
- }
- if (whitespaceHeuristics) {
- const r = this._deleteWordLeftWhitespace(model, position);
- if (r) {
- return r;
- }
- }
- let prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, position);
- if (wordNavigationType === 0 /* WordNavigationType.WordStart */) {
- if (prevWordOnLine) {
- column = prevWordOnLine.start + 1;
- }
- else {
- if (column > 1) {
- column = 1;
- }
- else {
- lineNumber--;
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- }
- else {
- if (prevWordOnLine && column <= prevWordOnLine.end + 1) {
- prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1));
- }
- if (prevWordOnLine) {
- column = prevWordOnLine.end + 1;
- }
- else {
- if (column > 1) {
- column = 1;
- }
- else {
- lineNumber--;
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- }
- return new Range(lineNumber, column, position.lineNumber, position.column);
- }
- static deleteInsideWord(wordSeparators, model, selection) {
- if (!selection.isEmpty()) {
- return selection;
- }
- const position = new Position(selection.positionLineNumber, selection.positionColumn);
- const r = this._deleteInsideWordWhitespace(model, position);
- if (r) {
- return r;
- }
- return this._deleteInsideWordDetermineDeleteRange(wordSeparators, model, position);
- }
- static _charAtIsWhitespace(str, index) {
- const charCode = str.charCodeAt(index);
- return (charCode === 32 /* CharCode.Space */ || charCode === 9 /* CharCode.Tab */);
- }
- static _deleteInsideWordWhitespace(model, position) {
- const lineContent = model.getLineContent(position.lineNumber);
- const lineContentLength = lineContent.length;
- if (lineContentLength === 0) {
- // empty line
- return null;
- }
- let leftIndex = Math.max(position.column - 2, 0);
- if (!this._charAtIsWhitespace(lineContent, leftIndex)) {
- // touches a non-whitespace character to the left
- return null;
- }
- let rightIndex = Math.min(position.column - 1, lineContentLength - 1);
- if (!this._charAtIsWhitespace(lineContent, rightIndex)) {
- // touches a non-whitespace character to the right
- return null;
- }
- // walk over whitespace to the left
- while (leftIndex > 0 && this._charAtIsWhitespace(lineContent, leftIndex - 1)) {
- leftIndex--;
- }
- // walk over whitespace to the right
- while (rightIndex + 1 < lineContentLength && this._charAtIsWhitespace(lineContent, rightIndex + 1)) {
- rightIndex++;
- }
- return new Range(position.lineNumber, leftIndex + 1, position.lineNumber, rightIndex + 2);
- }
- static _deleteInsideWordDetermineDeleteRange(wordSeparators, model, position) {
- const lineContent = model.getLineContent(position.lineNumber);
- const lineLength = lineContent.length;
- if (lineLength === 0) {
- // empty line
- if (position.lineNumber > 1) {
- return new Range(position.lineNumber - 1, model.getLineMaxColumn(position.lineNumber - 1), position.lineNumber, 1);
- }
- else {
- if (position.lineNumber < model.getLineCount()) {
- return new Range(position.lineNumber, 1, position.lineNumber + 1, 1);
- }
- else {
- // empty model
- return new Range(position.lineNumber, 1, position.lineNumber, 1);
- }
- }
- }
- const touchesWord = (word) => {
- return (word.start + 1 <= position.column && position.column <= word.end + 1);
- };
- const createRangeWithPosition = (startColumn, endColumn) => {
- startColumn = Math.min(startColumn, position.column);
- endColumn = Math.max(endColumn, position.column);
- return new Range(position.lineNumber, startColumn, position.lineNumber, endColumn);
- };
- const deleteWordAndAdjacentWhitespace = (word) => {
- let startColumn = word.start + 1;
- let endColumn = word.end + 1;
- let expandedToTheRight = false;
- while (endColumn - 1 < lineLength && this._charAtIsWhitespace(lineContent, endColumn - 1)) {
- expandedToTheRight = true;
- endColumn++;
- }
- if (!expandedToTheRight) {
- while (startColumn > 1 && this._charAtIsWhitespace(lineContent, startColumn - 2)) {
- startColumn--;
- }
- }
- return createRangeWithPosition(startColumn, endColumn);
- };
- const prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, position);
- if (prevWordOnLine && touchesWord(prevWordOnLine)) {
- return deleteWordAndAdjacentWhitespace(prevWordOnLine);
- }
- const nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, position);
- if (nextWordOnLine && touchesWord(nextWordOnLine)) {
- return deleteWordAndAdjacentWhitespace(nextWordOnLine);
- }
- if (prevWordOnLine && nextWordOnLine) {
- return createRangeWithPosition(prevWordOnLine.end + 1, nextWordOnLine.start + 1);
- }
- if (prevWordOnLine) {
- return createRangeWithPosition(prevWordOnLine.start + 1, prevWordOnLine.end + 1);
- }
- if (nextWordOnLine) {
- return createRangeWithPosition(nextWordOnLine.start + 1, nextWordOnLine.end + 1);
- }
- return createRangeWithPosition(1, lineLength + 1);
- }
- static _deleteWordPartLeft(model, selection) {
- if (!selection.isEmpty()) {
- return selection;
- }
- const pos = selection.getPosition();
- const toPosition = WordOperations._moveWordPartLeft(model, pos);
- return new Range(pos.lineNumber, pos.column, toPosition.lineNumber, toPosition.column);
- }
- static _findFirstNonWhitespaceChar(str, startIndex) {
- const len = str.length;
- for (let chIndex = startIndex; chIndex < len; chIndex++) {
- const ch = str.charAt(chIndex);
- if (ch !== ' ' && ch !== '\t') {
- return chIndex;
- }
- }
- return len;
- }
- static _deleteWordRightWhitespace(model, position) {
- const lineContent = model.getLineContent(position.lineNumber);
- const startIndex = position.column - 1;
- const firstNonWhitespace = this._findFirstNonWhitespaceChar(lineContent, startIndex);
- if (startIndex + 1 < firstNonWhitespace) {
- // bingo
- return new Range(position.lineNumber, position.column, position.lineNumber, firstNonWhitespace + 1);
- }
- return null;
- }
- static deleteWordRight(ctx, wordNavigationType) {
- const wordSeparators = ctx.wordSeparators;
- const model = ctx.model;
- const selection = ctx.selection;
- const whitespaceHeuristics = ctx.whitespaceHeuristics;
- if (!selection.isEmpty()) {
- return selection;
- }
- const position = new Position(selection.positionLineNumber, selection.positionColumn);
- let lineNumber = position.lineNumber;
- let column = position.column;
- const lineCount = model.getLineCount();
- const maxColumn = model.getLineMaxColumn(lineNumber);
- if (lineNumber === lineCount && column === maxColumn) {
- // Ignore deleting at end of file
- return null;
- }
- if (whitespaceHeuristics) {
- const r = this._deleteWordRightWhitespace(model, position);
- if (r) {
- return r;
- }
- }
- let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, position);
- if (wordNavigationType === 2 /* WordNavigationType.WordEnd */) {
- if (nextWordOnLine) {
- column = nextWordOnLine.end + 1;
- }
- else {
- if (column < maxColumn || lineNumber === lineCount) {
- column = maxColumn;
- }
- else {
- lineNumber++;
- nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, 1));
- if (nextWordOnLine) {
- column = nextWordOnLine.start + 1;
- }
- else {
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- }
- }
- else {
- if (nextWordOnLine && column >= nextWordOnLine.start + 1) {
- nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
- }
- if (nextWordOnLine) {
- column = nextWordOnLine.start + 1;
- }
- else {
- if (column < maxColumn || lineNumber === lineCount) {
- column = maxColumn;
- }
- else {
- lineNumber++;
- nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, 1));
- if (nextWordOnLine) {
- column = nextWordOnLine.start + 1;
- }
- else {
- column = model.getLineMaxColumn(lineNumber);
- }
- }
- }
- }
- return new Range(lineNumber, column, position.lineNumber, position.column);
- }
- static _deleteWordPartRight(model, selection) {
- if (!selection.isEmpty()) {
- return selection;
- }
- const pos = selection.getPosition();
- const toPosition = WordOperations._moveWordPartRight(model, pos);
- return new Range(pos.lineNumber, pos.column, toPosition.lineNumber, toPosition.column);
- }
- static _createWordAtPosition(model, lineNumber, word) {
- const range = new Range(lineNumber, word.start + 1, lineNumber, word.end + 1);
- return {
- word: model.getValueInRange(range),
- startColumn: range.startColumn,
- endColumn: range.endColumn
- };
- }
- static getWordAtPosition(model, _wordSeparators, position) {
- const wordSeparators = getMapForWordSeparators(_wordSeparators);
- const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position);
- if (prevWord && prevWord.wordType === 1 /* WordType.Regular */ && prevWord.start <= position.column - 1 && position.column - 1 <= prevWord.end) {
- return WordOperations._createWordAtPosition(model, position.lineNumber, prevWord);
- }
- const nextWord = WordOperations._findNextWordOnLine(wordSeparators, model, position);
- if (nextWord && nextWord.wordType === 1 /* WordType.Regular */ && nextWord.start <= position.column - 1 && position.column - 1 <= nextWord.end) {
- return WordOperations._createWordAtPosition(model, position.lineNumber, nextWord);
- }
- return null;
- }
- static word(config, model, cursor, inSelectionMode, position) {
- const wordSeparators = getMapForWordSeparators(config.wordSeparators);
- const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position);
- const nextWord = WordOperations._findNextWordOnLine(wordSeparators, model, position);
- if (!inSelectionMode) {
- // Entering word selection for the first time
- let startColumn;
- let endColumn;
- if (prevWord && prevWord.wordType === 1 /* WordType.Regular */ && prevWord.start <= position.column - 1 && position.column - 1 <= prevWord.end) {
- // isTouchingPrevWord
- startColumn = prevWord.start + 1;
- endColumn = prevWord.end + 1;
- }
- else if (nextWord && nextWord.wordType === 1 /* WordType.Regular */ && nextWord.start <= position.column - 1 && position.column - 1 <= nextWord.end) {
- // isTouchingNextWord
- startColumn = nextWord.start + 1;
- endColumn = nextWord.end + 1;
- }
- else {
- if (prevWord) {
- startColumn = prevWord.end + 1;
- }
- else {
- startColumn = 1;
- }
- if (nextWord) {
- endColumn = nextWord.start + 1;
- }
- else {
- endColumn = model.getLineMaxColumn(position.lineNumber);
- }
- }
- return new SingleCursorState(new Range(position.lineNumber, startColumn, position.lineNumber, endColumn), 0, new Position(position.lineNumber, endColumn), 0);
- }
- let startColumn;
- let endColumn;
- if (prevWord && prevWord.wordType === 1 /* WordType.Regular */ && prevWord.start < position.column - 1 && position.column - 1 < prevWord.end) {
- // isInsidePrevWord
- startColumn = prevWord.start + 1;
- endColumn = prevWord.end + 1;
- }
- else if (nextWord && nextWord.wordType === 1 /* WordType.Regular */ && nextWord.start < position.column - 1 && position.column - 1 < nextWord.end) {
- // isInsideNextWord
- startColumn = nextWord.start + 1;
- endColumn = nextWord.end + 1;
- }
- else {
- startColumn = position.column;
- endColumn = position.column;
- }
- const lineNumber = position.lineNumber;
- let column;
- if (cursor.selectionStart.containsPosition(position)) {
- column = cursor.selectionStart.endColumn;
- }
- else if (position.isBeforeOrEqual(cursor.selectionStart.getStartPosition())) {
- column = startColumn;
- const possiblePosition = new Position(lineNumber, column);
- if (cursor.selectionStart.containsPosition(possiblePosition)) {
- column = cursor.selectionStart.endColumn;
- }
- }
- else {
- column = endColumn;
- const possiblePosition = new Position(lineNumber, column);
- if (cursor.selectionStart.containsPosition(possiblePosition)) {
- column = cursor.selectionStart.startColumn;
- }
- }
- return cursor.move(true, lineNumber, column, 0);
- }
- }
- export class WordPartOperations extends WordOperations {
- static deleteWordPartLeft(ctx) {
- const candidates = enforceDefined([
- WordOperations.deleteWordLeft(ctx, 0 /* WordNavigationType.WordStart */),
- WordOperations.deleteWordLeft(ctx, 2 /* WordNavigationType.WordEnd */),
- WordOperations._deleteWordPartLeft(ctx.model, ctx.selection)
- ]);
- candidates.sort(Range.compareRangesUsingEnds);
- return candidates[2];
- }
- static deleteWordPartRight(ctx) {
- const candidates = enforceDefined([
- WordOperations.deleteWordRight(ctx, 0 /* WordNavigationType.WordStart */),
- WordOperations.deleteWordRight(ctx, 2 /* WordNavigationType.WordEnd */),
- WordOperations._deleteWordPartRight(ctx.model, ctx.selection)
- ]);
- candidates.sort(Range.compareRangesUsingStarts);
- return candidates[0];
- }
- static moveWordPartLeft(wordSeparators, model, position) {
- const candidates = enforceDefined([
- WordOperations.moveWordLeft(wordSeparators, model, position, 0 /* WordNavigationType.WordStart */),
- WordOperations.moveWordLeft(wordSeparators, model, position, 2 /* WordNavigationType.WordEnd */),
- WordOperations._moveWordPartLeft(model, position)
- ]);
- candidates.sort(Position.compare);
- return candidates[2];
- }
- static moveWordPartRight(wordSeparators, model, position) {
- const candidates = enforceDefined([
- WordOperations.moveWordRight(wordSeparators, model, position, 0 /* WordNavigationType.WordStart */),
- WordOperations.moveWordRight(wordSeparators, model, position, 2 /* WordNavigationType.WordEnd */),
- WordOperations._moveWordPartRight(model, position)
- ]);
- candidates.sort(Position.compare);
- return candidates[0];
- }
- }
- function enforceDefined(arr) {
- return arr.filter(el => Boolean(el));
- }
|