diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 1950771ff4116..74ae2f633ea9f 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -463,7 +463,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE if (!this._modelData) { return null; } - return WordOperations.getWordAtPosition(this._modelData.model, this._configuration.options.get(EditorOption.wordSeparators), position); + return WordOperations.getWordAtPosition(this._modelData.model, this._configuration.options.get(EditorOption.wordSeparators), position, this._configuration.options.get(EditorOption.recognizeWordLocales)); } public getValue(options: { preserveBOM: boolean; lineEnding: string } | null = null): string { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 73fc32d3b34a5..bb6f3dd221f04 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -160,6 +160,13 @@ export interface IEditorOptions { * The message to display when the editor is readonly. */ readOnlyMessage?: IMarkdownString; + /** + * Locales that recognizes word separators when doing word related navigations or operations. + * + * Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.). If you specify more than one, separate them with a comma. + * If the default setting is blank, or if all specified BCP 47 language tags are not supported, the word will not be recognized. + */ + recognizeWordLocales?: string; /** * Should the textarea used for input use the DOM `readonly` attribute. * Defaults to false. @@ -3564,6 +3571,50 @@ class ReadonlyMessage extends BaseEditorOption { + constructor() { + const defaults: string[] = []; + + super( + EditorOption.recognizeWordLocales, 'recognizeWordLocales', defaults, + { + type: 'string', + description: nls.localize('recognizeWordLocales', "Locales that recognizes word separators when doing word related navigations or operations. Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.). If you specify more than one, separate them with a comma.If the default setting is blank, or if all specified BCP 47 language tags are not supported, the word will not be recognized."), + } + ); + } + + public validate(input: any): string[] { + if (typeof input === 'string') { + const input_locales = input.split(',').map((item) => item.trim()); + const valid_locales: string[] = []; + for (const locale of input_locales) { + try { + if (Intl.Segmenter.supportedLocalesOf(locale).length > 0) { + valid_locales.push(locale); + } + } catch (_) { + // ignore invalid locales + } + } + return valid_locales; + } + + return this.defaultValue; + } +} + + //#endregion //#region scrollbar @@ -5161,6 +5212,7 @@ export const enum EditorOption { quickSuggestionsDelay, readOnly, readOnlyMessage, + recognizeWordLocales, renameOnType, renderControlCharacters, renderFinalNewline, @@ -5699,6 +5751,7 @@ export const EditorOptions = { EditorOption.readOnly, 'readOnly', false, )), readOnlyMessage: register(new ReadonlyMessage()), + recognizeWordLocales: register(new RecognizeWordLocales()), renameOnType: register(new EditorBooleanOption( EditorOption.renameOnType, 'renameOnType', false, { description: nls.localize('renameOnType', "Controls whether the editor auto renames on type."), markdownDeprecationMessage: nls.localize('renameOnTypeDeprecate', "Deprecated, use `editor.linkedEditing` instead.") } diff --git a/src/vs/editor/common/cursor/cursorWordOperations.ts b/src/vs/editor/common/cursor/cursorWordOperations.ts index 8a3f98d37c237..b4821374fa540 100644 --- a/src/vs/editor/common/cursor/cursorWordOperations.ts +++ b/src/vs/editor/common/cursor/cursorWordOperations.ts @@ -58,56 +58,95 @@ export interface DeleteWordContext { autoClosingQuotes: EditorAutoClosingStrategy; autoClosingPairs: AutoClosingPairs; autoClosedCharacters: Range[]; + recognizeWordLocales: string[]; } export class WordOperations { private static _createWord(lineContent: string, wordType: WordType, nextCharClass: WordCharacterClass, start: number, end: number): IFindWordResult { - // console.log('WORD ==> ' + start + ' => ' + end + ':::: <<<' + lineContent.substring(start, end) + '>>>'); return { start: start, end: end, wordType: wordType, nextCharClass: nextCharClass }; } - private static _findPreviousWordOnLine(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position): IFindWordResult | null { + private static _findPreviousWordOnLine(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, recognizeWordLocales: string[]): IFindWordResult | null { const lineContent = model.getLineContent(position.lineNumber); - return this._doFindPreviousWordOnLine(lineContent, wordSeparators, position); + return this._doFindPreviousWordOnLine(lineContent, wordSeparators, position, recognizeWordLocales); } - private static _doFindPreviousWordOnLine(lineContent: string, wordSeparators: WordCharacterClassifier, position: Position): IFindWordResult | null { + private static _doFindPreviousWordOnLine(lineContent: string, wordSeparators: WordCharacterClassifier, position: Position, recognizeWordLocales: string[]): IFindWordResult | null { let wordType = WordType.None; + + const wordLikeChIndices: number[] = []; + + if (recognizeWordLocales.length) { + const segmenter = new Intl.Segmenter(recognizeWordLocales, { granularity: 'word' }); + const segments = segmenter.segment(lineContent); + + for (const segment of segments) { + if (segment.isWordLike) { + wordLikeChIndices.push(segment.index); + } + } + } + for (let chIndex = position.column - 2; chIndex >= 0; chIndex--) { const chCode = lineContent.charCodeAt(chIndex); const chClass = wordSeparators.get(chCode); + for (const wordLikeChIndex of wordLikeChIndices) { + if (chIndex === wordLikeChIndex) { + return this._createWord(lineContent, wordType, chClass, chIndex, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex, recognizeWordLocales)); + } + } + if (chClass === WordCharacterClass.Regular) { if (wordType === WordType.Separator) { - return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); + return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1, recognizeWordLocales)); } wordType = WordType.Regular; } else if (chClass === WordCharacterClass.WordSeparator) { if (wordType === WordType.Regular) { - return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); + return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1, recognizeWordLocales)); } wordType = WordType.Separator; } else if (chClass === WordCharacterClass.Whitespace) { if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1)); + return this._createWord(lineContent, wordType, chClass, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1, recognizeWordLocales)); } } } if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, WordCharacterClass.Whitespace, 0, this._findEndOfWord(lineContent, wordSeparators, wordType, 0)); + return this._createWord(lineContent, wordType, WordCharacterClass.Whitespace, 0, this._findEndOfWord(lineContent, wordSeparators, wordType, 0, recognizeWordLocales)); } return null; } - private static _findEndOfWord(lineContent: string, wordSeparators: WordCharacterClassifier, wordType: WordType, startIndex: number): number { + private static _findEndOfWord(lineContent: string, wordSeparators: WordCharacterClassifier, wordType: WordType, startIndex: number, recognizeWordLocales: string[]): number { + const wordLikeChIndices: number[] = []; + + if (recognizeWordLocales.length) { + const segmenter = new Intl.Segmenter(recognizeWordLocales, { granularity: 'word' }); + const segments = segmenter.segment(lineContent); + + for (const segment of segments) { + if (segment.isWordLike) { + wordLikeChIndices.push(segment.index + segment.segment.length); + } + } + } + const len = lineContent.length; for (let chIndex = startIndex; chIndex < len; chIndex++) { const chCode = lineContent.charCodeAt(chIndex); const chClass = wordSeparators.get(chCode); + for (const wordLikeChIndex of wordLikeChIndices) { + if (chIndex === wordLikeChIndex) { + return chIndex; + } + } + if (chClass === WordCharacterClass.Whitespace) { return chIndex; } @@ -121,48 +160,88 @@ export class WordOperations { return len; } - private static _findNextWordOnLine(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position): IFindWordResult | null { + private static _findNextWordOnLine(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, recognizeWordLocales: string[]): IFindWordResult | null { const lineContent = model.getLineContent(position.lineNumber); - return this._doFindNextWordOnLine(lineContent, wordSeparators, position); + return this._doFindNextWordOnLine(lineContent, wordSeparators, position, recognizeWordLocales); } - private static _doFindNextWordOnLine(lineContent: string, wordSeparators: WordCharacterClassifier, position: Position): IFindWordResult | null { + private static _doFindNextWordOnLine(lineContent: string, wordSeparators: WordCharacterClassifier, position: Position, recognizeWordLocales: string[]): IFindWordResult | null { let wordType = WordType.None; const len = lineContent.length; + const wordLikeChIndices = []; + if (recognizeWordLocales.length) { + const segmenter = new Intl.Segmenter(recognizeWordLocales, { granularity: 'word' }); + const segments = segmenter.segment(lineContent); + + for (const segment of segments) { + if (segment.isWordLike) { + wordLikeChIndices.push(segment.index + segment.segment.length); + } + } + } + for (let chIndex = position.column - 1; chIndex < len; chIndex++) { const chCode = lineContent.charCodeAt(chIndex); const chClass = wordSeparators.get(chCode); + for (let i = 0; i < wordLikeChIndices.length - 1; i++) { + if (position.column - 1 === chIndex) { + continue; + } + + if (chIndex === wordLikeChIndices[i]) { + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, wordLikeChIndices[i] - 1, recognizeWordLocales), wordLikeChIndices[i]); + } + } + if (chClass === WordCharacterClass.Regular) { if (wordType === WordType.Separator) { - return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1, recognizeWordLocales), chIndex); } wordType = WordType.Regular; } else if (chClass === WordCharacterClass.WordSeparator) { if (wordType === WordType.Regular) { - return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1, recognizeWordLocales), chIndex); } wordType = WordType.Separator; } else if (chClass === WordCharacterClass.Whitespace) { if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex); + return this._createWord(lineContent, wordType, chClass, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1, recognizeWordLocales), chIndex); } } } if (wordType !== WordType.None) { - return this._createWord(lineContent, wordType, WordCharacterClass.Whitespace, this._findStartOfWord(lineContent, wordSeparators, wordType, len - 1), len); + return this._createWord(lineContent, wordType, WordCharacterClass.Whitespace, this._findStartOfWord(lineContent, wordSeparators, wordType, len - 1, recognizeWordLocales), len); } return null; } - private static _findStartOfWord(lineContent: string, wordSeparators: WordCharacterClassifier, wordType: WordType, startIndex: number): number { + private static _findStartOfWord(lineContent: string, wordSeparators: WordCharacterClassifier, wordType: WordType, startIndex: number, recognizeWordLocales: string[]): number { + const wordLikeChIndices = []; + if (recognizeWordLocales.length) { + const segmenter = new Intl.Segmenter(recognizeWordLocales, { granularity: 'word' }); + const segments = segmenter.segment(lineContent); + + for (const segment of segments) { + if (segment.isWordLike) { + wordLikeChIndices.push(segment.index); + } + } + } + for (let chIndex = startIndex; chIndex >= 0; chIndex--) { const chCode = lineContent.charCodeAt(chIndex); const chClass = wordSeparators.get(chCode); + for (const wordLikeChIndex of wordLikeChIndices) { + if (chIndex === wordLikeChIndex) { + return chIndex; + } + } + if (chClass === WordCharacterClass.Whitespace) { return chIndex + 1; } @@ -176,7 +255,7 @@ export class WordOperations { return 0; } - public static moveWordLeft(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, wordNavigationType: WordNavigationType): Position { + public static moveWordLeft(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { let lineNumber = position.lineNumber; let column = position.column; @@ -187,7 +266,7 @@ export class WordOperations { } } - let prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, column)); + let prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, column), recognizeWordLocales); if (wordNavigationType === WordNavigationType.WordStart) { return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1); @@ -201,7 +280,7 @@ export class WordOperations { && prevWordOnLine.nextCharClass === 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)); + prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1), recognizeWordLocales); } return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1); @@ -213,7 +292,7 @@ export class WordOperations { && prevWordOnLine.wordType === WordType.Separator ) { // Skip over words made up of only separators - prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1)); + prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1), recognizeWordLocales); } return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1); @@ -222,7 +301,7 @@ export class WordOperations { // 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)); + prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1), recognizeWordLocales); } return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.end + 1 : 1); @@ -270,7 +349,7 @@ export class WordOperations { return new Position(lineNumber, 1); } - public static moveWordRight(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, wordNavigationType: WordNavigationType): Position { + public static moveWordRight(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { let lineNumber = position.lineNumber; let column = position.column; @@ -283,13 +362,13 @@ export class WordOperations { } } - let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, column)); + let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, column), recognizeWordLocales); if (wordNavigationType === WordNavigationType.WordEnd) { if (nextWordOnLine && nextWordOnLine.wordType === WordType.Separator) { if (nextWordOnLine.end - nextWordOnLine.start === 1 && nextWordOnLine.nextCharClass === 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)); + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1), recognizeWordLocales); } } if (nextWordOnLine) { @@ -313,7 +392,7 @@ export class WordOperations { ) { // 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)); + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1), recognizeWordLocales); } if (nextWordOnLine) { @@ -323,7 +402,7 @@ export class WordOperations { } } else { if (nextWordOnLine && !movedDown && column >= nextWordOnLine.start + 1) { - nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1)); + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1), recognizeWordLocales); } if (nextWordOnLine) { column = nextWordOnLine.start + 1; @@ -419,7 +498,7 @@ export class WordOperations { } } - let prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, position); + let prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, position, ctx.recognizeWordLocales); if (wordNavigationType === WordNavigationType.WordStart) { if (prevWordOnLine) { @@ -434,7 +513,7 @@ export class WordOperations { } } else { if (prevWordOnLine && column <= prevWordOnLine.end + 1) { - prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1)); + prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1), ctx.recognizeWordLocales); } if (prevWordOnLine) { column = prevWordOnLine.end + 1; @@ -451,7 +530,7 @@ export class WordOperations { return new Range(lineNumber, column, position.lineNumber, position.column); } - public static deleteInsideWord(wordSeparators: WordCharacterClassifier, model: ITextModel, selection: Selection): Range { + public static deleteInsideWord(wordSeparators: WordCharacterClassifier, model: ITextModel, selection: Selection, recognizeWordLocales: string[]): Range { if (!selection.isEmpty()) { return selection; } @@ -463,7 +542,7 @@ export class WordOperations { return r; } - return this._deleteInsideWordDetermineDeleteRange(wordSeparators, model, position); + return this._deleteInsideWordDetermineDeleteRange(wordSeparators, model, position, recognizeWordLocales); } private static _charAtIsWhitespace(str: string, index: number): boolean { @@ -505,7 +584,7 @@ export class WordOperations { return new Range(position.lineNumber, leftIndex + 1, position.lineNumber, rightIndex + 2); } - private static _deleteInsideWordDetermineDeleteRange(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position): Range { + private static _deleteInsideWordDetermineDeleteRange(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, recognizeWordLocales: string[]): Range { const lineContent = model.getLineContent(position.lineNumber); const lineLength = lineContent.length; if (lineLength === 0) { @@ -546,11 +625,11 @@ export class WordOperations { return createRangeWithPosition(startColumn, endColumn); }; - const prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, position); + const prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, position, recognizeWordLocales); if (prevWordOnLine && touchesWord(prevWordOnLine)) { return deleteWordAndAdjacentWhitespace(prevWordOnLine); } - const nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, position); + const nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, position, recognizeWordLocales); if (nextWordOnLine && touchesWord(nextWordOnLine)) { return deleteWordAndAdjacentWhitespace(nextWordOnLine); } @@ -604,6 +683,7 @@ export class WordOperations { const model = ctx.model; const selection = ctx.selection; const whitespaceHeuristics = ctx.whitespaceHeuristics; + const recognizeWordLocales = ctx.recognizeWordLocales; if (!selection.isEmpty()) { return selection; @@ -628,7 +708,7 @@ export class WordOperations { } } - let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, position); + let nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, position, recognizeWordLocales); if (wordNavigationType === WordNavigationType.WordEnd) { if (nextWordOnLine) { @@ -638,7 +718,7 @@ export class WordOperations { column = maxColumn; } else { lineNumber++; - nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, 1)); + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, 1), recognizeWordLocales); if (nextWordOnLine) { column = nextWordOnLine.start + 1; } else { @@ -648,7 +728,7 @@ export class WordOperations { } } else { if (nextWordOnLine && column >= nextWordOnLine.start + 1) { - nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1)); + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1), recognizeWordLocales); } if (nextWordOnLine) { column = nextWordOnLine.start + 1; @@ -657,7 +737,7 @@ export class WordOperations { column = maxColumn; } else { lineNumber++; - nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, 1)); + nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, 1), recognizeWordLocales); if (nextWordOnLine) { column = nextWordOnLine.start + 1; } else { @@ -689,13 +769,13 @@ export class WordOperations { }; } - public static getWordAtPosition(model: ITextModel, _wordSeparators: string, position: Position): IWordAtPosition | null { + public static getWordAtPosition(model: ITextModel, _wordSeparators: string, position: Position, recognizeWordLocales: string[]): IWordAtPosition | null { const wordSeparators = getMapForWordSeparators(_wordSeparators); - const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position); + const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position, recognizeWordLocales); if (prevWord && prevWord.wordType === 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); + const nextWord = WordOperations._findNextWordOnLine(wordSeparators, model, position, recognizeWordLocales); if (nextWord && nextWord.wordType === WordType.Regular && nextWord.start <= position.column - 1 && position.column - 1 <= nextWord.end) { return WordOperations._createWordAtPosition(model, position.lineNumber, nextWord); } @@ -704,8 +784,9 @@ export class WordOperations { public static word(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean, position: Position): SingleCursorState { const wordSeparators = getMapForWordSeparators(config.wordSeparators); - const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position); - const nextWord = WordOperations._findNextWordOnLine(wordSeparators, model, position); + const recognizeWordLocales = config.recognizeWordLocales; + const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position, recognizeWordLocales); + const nextWord = WordOperations._findNextWordOnLine(wordSeparators, model, position, recognizeWordLocales); if (!inSelectionMode) { // Entering word selection for the first time @@ -798,20 +879,20 @@ export class WordPartOperations extends WordOperations { return candidates[0]; } - public static moveWordPartLeft(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position): Position { + public static moveWordPartLeft(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, recognizeWordLocales: string[]): Position { const candidates = enforceDefined([ - WordOperations.moveWordLeft(wordSeparators, model, position, WordNavigationType.WordStart), - WordOperations.moveWordLeft(wordSeparators, model, position, WordNavigationType.WordEnd), + WordOperations.moveWordLeft(wordSeparators, model, position, WordNavigationType.WordStart, recognizeWordLocales), + WordOperations.moveWordLeft(wordSeparators, model, position, WordNavigationType.WordEnd, recognizeWordLocales), WordOperations._moveWordPartLeft(model, position) ]); candidates.sort(Position.compare); return candidates[2]; } - public static moveWordPartRight(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position): Position { + public static moveWordPartRight(wordSeparators: WordCharacterClassifier, model: ICursorSimpleModel, position: Position, recognizeWordLocales: string[]): Position { const candidates = enforceDefined([ - WordOperations.moveWordRight(wordSeparators, model, position, WordNavigationType.WordStart), - WordOperations.moveWordRight(wordSeparators, model, position, WordNavigationType.WordEnd), + WordOperations.moveWordRight(wordSeparators, model, position, WordNavigationType.WordStart, recognizeWordLocales), + WordOperations.moveWordRight(wordSeparators, model, position, WordNavigationType.WordEnd, recognizeWordLocales), WordOperations._moveWordPartRight(model, position) ]); candidates.sort(Position.compare); diff --git a/src/vs/editor/common/cursorCommon.ts b/src/vs/editor/common/cursorCommon.ts index 13b95ad129970..f68a5d77ae3fc 100644 --- a/src/vs/editor/common/cursorCommon.ts +++ b/src/vs/editor/common/cursorCommon.ts @@ -76,6 +76,7 @@ export class CursorConfiguration { public readonly surroundingPairs: CharacterMap; public readonly blockCommentStartToken: string | null; public readonly shouldAutoCloseBefore: { quote: (ch: string) => boolean; bracket: (ch: string) => boolean; comment: (ch: string) => boolean }; + public readonly recognizeWordLocales: string[]; private readonly _languageId: string; private _electricChars: { [key: string]: boolean } | null; @@ -97,6 +98,7 @@ export class CursorConfiguration { || e.hasChanged(EditorOption.useTabStops) || e.hasChanged(EditorOption.fontInfo) || e.hasChanged(EditorOption.readOnly) + || e.hasChanged(EditorOption.recognizeWordLocales) ); } @@ -134,6 +136,7 @@ export class CursorConfiguration { this.autoClosingOvertype = options.get(EditorOption.autoClosingOvertype); this.autoSurround = options.get(EditorOption.autoSurround); this.autoIndent = options.get(EditorOption.autoIndent); + this.recognizeWordLocales = options.get(EditorOption.recognizeWordLocales); this.surroundingPairs = {}; this._electricChars = null; diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index bbdeb0560ff61..f3249670cc131 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -265,62 +265,63 @@ export enum EditorOption { quickSuggestionsDelay = 89, readOnly = 90, readOnlyMessage = 91, - renameOnType = 92, - renderControlCharacters = 93, - renderFinalNewline = 94, - renderLineHighlight = 95, - renderLineHighlightOnlyWhenFocus = 96, - renderValidationDecorations = 97, - renderWhitespace = 98, - revealHorizontalRightPadding = 99, - roundedSelection = 100, - rulers = 101, - scrollbar = 102, - scrollBeyondLastColumn = 103, - scrollBeyondLastLine = 104, - scrollPredominantAxis = 105, - selectionClipboard = 106, - selectionHighlight = 107, - selectOnLineNumbers = 108, - showFoldingControls = 109, - showUnused = 110, - snippetSuggestions = 111, - smartSelect = 112, - smoothScrolling = 113, - stickyScroll = 114, - stickyTabStops = 115, - stopRenderingLineAfter = 116, - suggest = 117, - suggestFontSize = 118, - suggestLineHeight = 119, - suggestOnTriggerCharacters = 120, - suggestSelection = 121, - tabCompletion = 122, - tabIndex = 123, - unicodeHighlighting = 124, - unusualLineTerminators = 125, - useShadowDOM = 126, - useTabStops = 127, - wordBreak = 128, - wordSeparators = 129, - wordWrap = 130, - wordWrapBreakAfterCharacters = 131, - wordWrapBreakBeforeCharacters = 132, - wordWrapColumn = 133, - wordWrapOverride1 = 134, - wordWrapOverride2 = 135, - wrappingIndent = 136, - wrappingStrategy = 137, - showDeprecated = 138, - inlayHints = 139, - editorClassName = 140, - pixelRatio = 141, - tabFocusMode = 142, - layoutInfo = 143, - wrappingInfo = 144, - defaultColorDecorators = 145, - colorDecoratorsActivatedOn = 146, - inlineCompletionsAccessibilityVerbose = 147 + recognizeWordLocales = 92, + renameOnType = 93, + renderControlCharacters = 94, + renderFinalNewline = 95, + renderLineHighlight = 96, + renderLineHighlightOnlyWhenFocus = 97, + renderValidationDecorations = 98, + renderWhitespace = 99, + revealHorizontalRightPadding = 100, + roundedSelection = 101, + rulers = 102, + scrollbar = 103, + scrollBeyondLastColumn = 104, + scrollBeyondLastLine = 105, + scrollPredominantAxis = 106, + selectionClipboard = 107, + selectionHighlight = 108, + selectOnLineNumbers = 109, + showFoldingControls = 110, + showUnused = 111, + snippetSuggestions = 112, + smartSelect = 113, + smoothScrolling = 114, + stickyScroll = 115, + stickyTabStops = 116, + stopRenderingLineAfter = 117, + suggest = 118, + suggestFontSize = 119, + suggestLineHeight = 120, + suggestOnTriggerCharacters = 121, + suggestSelection = 122, + tabCompletion = 123, + tabIndex = 124, + unicodeHighlighting = 125, + unusualLineTerminators = 126, + useShadowDOM = 127, + useTabStops = 128, + wordBreak = 129, + wordSeparators = 130, + wordWrap = 131, + wordWrapBreakAfterCharacters = 132, + wordWrapBreakBeforeCharacters = 133, + wordWrapColumn = 134, + wordWrapOverride1 = 135, + wordWrapOverride2 = 136, + wrappingIndent = 137, + wrappingStrategy = 138, + showDeprecated = 139, + inlayHints = 140, + editorClassName = 141, + pixelRatio = 142, + tabFocusMode = 143, + layoutInfo = 144, + wrappingInfo = 145, + defaultColorDecorators = 146, + colorDecoratorsActivatedOn = 147, + inlineCompletionsAccessibilityVerbose = 148 } /** diff --git a/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts b/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts index 6d78b46096532..3776c012d757d 100644 --- a/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts +++ b/src/vs/editor/contrib/wordOperations/browser/wordOperations.ts @@ -48,10 +48,11 @@ export abstract class MoveWordCommand extends EditorCommand { const wordSeparators = getMapForWordSeparators(editor.getOption(EditorOption.wordSeparators)); const model = editor.getModel(); const selections = editor.getSelections(); + const recognizeWordLocales = editor.getOption(EditorOption.recognizeWordLocales); const result = selections.map((sel) => { const inPosition = new Position(sel.positionLineNumber, sel.positionColumn); - const outPosition = this._move(wordSeparators, model, inPosition, this._wordNavigationType); + const outPosition = this._move(wordSeparators, model, inPosition, this._wordNavigationType, recognizeWordLocales); return this._moveTo(sel, outPosition, this._inSelectionMode); }); @@ -83,18 +84,18 @@ export abstract class MoveWordCommand extends EditorCommand { } } - protected abstract _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position; + protected abstract _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position; } export class WordLeftCommand extends MoveWordCommand { - protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return WordOperations.moveWordLeft(wordSeparators, model, position, wordNavigationType); + protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return WordOperations.moveWordLeft(wordSeparators, model, position, wordNavigationType, recognizeWordLocales); } } export class WordRightCommand extends MoveWordCommand { - protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return WordOperations.moveWordRight(wordSeparators, model, position, wordNavigationType); + protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return WordOperations.moveWordRight(wordSeparators, model, position, wordNavigationType, recognizeWordLocales); } } @@ -187,8 +188,8 @@ export class CursorWordAccessibilityLeft extends WordLeftCommand { }); } - protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType); + protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType, recognizeWordLocales); } } @@ -202,8 +203,8 @@ export class CursorWordAccessibilityLeftSelect extends WordLeftCommand { }); } - protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType); + protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType, recognizeWordLocales); } } @@ -295,8 +296,8 @@ export class CursorWordAccessibilityRight extends WordRightCommand { }); } - protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType); + protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType, recognizeWordLocales); } } @@ -310,8 +311,8 @@ export class CursorWordAccessibilityRightSelect extends WordRightCommand { }); } - protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType); + protected override _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return super._move(getMapForWordSeparators(EditorOptions.wordSeparators.defaultValue), model, position, wordNavigationType, recognizeWordLocales); } } @@ -354,7 +355,8 @@ export abstract class DeleteWordCommand extends EditorCommand { autoClosingBrackets, autoClosingQuotes, autoClosingPairs, - autoClosedCharacters: viewModel.getCursorAutoClosedCharacters() + autoClosedCharacters: viewModel.getCursorAutoClosedCharacters(), + recognizeWordLocales: editor.getOption(EditorOption.recognizeWordLocales) }, this._wordNavigationType); return new ReplaceCommand(deleteRange, ''); }); @@ -485,9 +487,10 @@ export class DeleteInsideWord extends EditorAction { const wordSeparators = getMapForWordSeparators(editor.getOption(EditorOption.wordSeparators)); const model = editor.getModel(); const selections = editor.getSelections(); + const recognizeWordLocales = editor.getOption(EditorOption.recognizeWordLocales); const commands = selections.map((sel) => { - const deleteRange = WordOperations.deleteInsideWord(wordSeparators, model, sel); + const deleteRange = WordOperations.deleteInsideWord(wordSeparators, model, sel, recognizeWordLocales); return new ReplaceCommand(deleteRange, ''); }); diff --git a/src/vs/editor/contrib/wordOperations/test/browser/wordOperations.test.ts b/src/vs/editor/contrib/wordOperations/test/browser/wordOperations.test.ts index 399d020170e9e..52c438eec84ac 100644 --- a/src/vs/editor/contrib/wordOperations/test/browser/wordOperations.test.ts +++ b/src/vs/editor/contrib/wordOperations/test/browser/wordOperations.test.ts @@ -179,6 +179,44 @@ suite('WordOperations', () => { assert.deepStrictEqual(actual, EXPECTED); }); + test('cursorWordLeft - Recognize words', () => { + const EXPECTED = [ + '|/* |これ|は|テスト|です |/*', + ].join('\n'); + const [text,] = deserializePipePositions(EXPECTED); + const actualStops = testRepeatedActionAndExtractPositions( + text, + new Position(1000, 1000), + ed => cursorWordLeft(ed, true), + ed => ed.getPosition()!, + ed => ed.getPosition()!.equals(new Position(1, 1)), + { + recognizeWordLocales: 'ja' + } + ); + const actual = serializePipePositions(text, actualStops); + assert.deepStrictEqual(actual, EXPECTED); + }); + + test('cursorWordLeft - Does not recognize words', () => { + const EXPECTED = [ + '|/* |これはテストです |/*', + ].join('\n'); + const [text,] = deserializePipePositions(EXPECTED); + const actualStops = testRepeatedActionAndExtractPositions( + text, + new Position(1000, 1000), + ed => cursorWordLeft(ed, true), + ed => ed.getPosition()!, + ed => ed.getPosition()!.equals(new Position(1, 1)), + { + recognizeWordLocales: '' + } + ); + const actual = serializePipePositions(text, actualStops); + assert.deepStrictEqual(actual, EXPECTED); + }); + test('cursorWordLeftSelect - issue #74369: cursorWordLeft and cursorWordLeftSelect do not behave consistently', () => { const EXPECTED = [ '|this.|is.|a.|test', @@ -195,6 +233,7 @@ suite('WordOperations', () => { assert.deepStrictEqual(actual, EXPECTED); }); + test('cursorWordStartLeft', () => { // This is the behaviour observed in Visual Studio, please do not touch test const EXPECTED = ['| |/* |Just |some |more |text |a|+= |3 |+|5|-|3 |+ |7 |*/ '].join('\n'); @@ -327,6 +366,44 @@ suite('WordOperations', () => { assert.deepStrictEqual(actual, EXPECTED); }); + test('cursorWordRight - Recognize words', () => { + const EXPECTED = [ + '/*| これ|は|テスト|です|/*|', + ].join('\n'); + const [text,] = deserializePipePositions(EXPECTED); + const actualStops = testRepeatedActionAndExtractPositions( + text, + new Position(1, 1), + ed => cursorWordRight(ed), + ed => ed.getPosition()!, + ed => ed.getPosition()!.equals(new Position(1, 14)), + { + recognizeWordLocales: 'ja' + } + ); + const actual = serializePipePositions(text, actualStops); + assert.deepStrictEqual(actual, EXPECTED); + }); + + test('cursorWordRight - Does not recognize words', () => { + const EXPECTED = [ + '/*| これはテストです|/*|', + ].join('\n'); + const [text,] = deserializePipePositions(EXPECTED); + const actualStops = testRepeatedActionAndExtractPositions( + text, + new Position(1, 1), + ed => cursorWordRight(ed), + ed => ed.getPosition()!, + ed => ed.getPosition()!.equals(new Position(1, 14)), + { + recognizeWordLocales: '' + } + ); + const actual = serializePipePositions(text, actualStops); + assert.deepStrictEqual(actual, EXPECTED); + }); + test('moveWordEndRight', () => { const EXPECTED = [ ' /*| Just| some| more| text| a|+=| 3| +5|-3| +| 7| */| |', diff --git a/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts b/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts index ebcabc415a474..75a2c30abbf37 100644 --- a/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts +++ b/src/vs/editor/contrib/wordPartOperations/browser/wordPartOperations.ts @@ -68,8 +68,8 @@ export class DeleteWordPartRight extends DeleteWordCommand { } export class WordPartLeftCommand extends MoveWordCommand { - protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return WordPartOperations.moveWordPartLeft(wordSeparators, model, position); + protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return WordPartOperations.moveWordPartLeft(wordSeparators, model, position, recognizeWordLocales); } } export class CursorWordPartLeft extends WordPartLeftCommand { @@ -111,8 +111,8 @@ export class CursorWordPartLeftSelect extends WordPartLeftCommand { CommandsRegistry.registerCommandAlias('cursorWordPartStartLeftSelect', 'cursorWordPartLeftSelect'); export class WordPartRightCommand extends MoveWordCommand { - protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position { - return WordPartOperations.moveWordPartRight(wordSeparators, model, position); + protected _move(wordSeparators: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType, recognizeWordLocales: string[]): Position { + return WordPartOperations.moveWordPartRight(wordSeparators, model, position, recognizeWordLocales); } } export class CursorWordPartRight extends WordPartRightCommand { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index ed1b548900fe5..2566e4977fe88 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3187,6 +3187,13 @@ declare namespace monaco.editor { * The message to display when the editor is readonly. */ readOnlyMessage?: IMarkdownString; + /** + * Locales that recognizes word separators when doing word related navigations or operations. + * + * Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.). If you specify more than one, separate them with a comma. + * If the default setting is blank, or if all specified BCP 47 language tags are not supported, the word will not be recognized. + */ + recognizeWordLocales?: string; /** * Should the textarea used for input use the DOM `readonly` attribute. * Defaults to false. @@ -4872,62 +4879,63 @@ declare namespace monaco.editor { quickSuggestionsDelay = 89, readOnly = 90, readOnlyMessage = 91, - renameOnType = 92, - renderControlCharacters = 93, - renderFinalNewline = 94, - renderLineHighlight = 95, - renderLineHighlightOnlyWhenFocus = 96, - renderValidationDecorations = 97, - renderWhitespace = 98, - revealHorizontalRightPadding = 99, - roundedSelection = 100, - rulers = 101, - scrollbar = 102, - scrollBeyondLastColumn = 103, - scrollBeyondLastLine = 104, - scrollPredominantAxis = 105, - selectionClipboard = 106, - selectionHighlight = 107, - selectOnLineNumbers = 108, - showFoldingControls = 109, - showUnused = 110, - snippetSuggestions = 111, - smartSelect = 112, - smoothScrolling = 113, - stickyScroll = 114, - stickyTabStops = 115, - stopRenderingLineAfter = 116, - suggest = 117, - suggestFontSize = 118, - suggestLineHeight = 119, - suggestOnTriggerCharacters = 120, - suggestSelection = 121, - tabCompletion = 122, - tabIndex = 123, - unicodeHighlighting = 124, - unusualLineTerminators = 125, - useShadowDOM = 126, - useTabStops = 127, - wordBreak = 128, - wordSeparators = 129, - wordWrap = 130, - wordWrapBreakAfterCharacters = 131, - wordWrapBreakBeforeCharacters = 132, - wordWrapColumn = 133, - wordWrapOverride1 = 134, - wordWrapOverride2 = 135, - wrappingIndent = 136, - wrappingStrategy = 137, - showDeprecated = 138, - inlayHints = 139, - editorClassName = 140, - pixelRatio = 141, - tabFocusMode = 142, - layoutInfo = 143, - wrappingInfo = 144, - defaultColorDecorators = 145, - colorDecoratorsActivatedOn = 146, - inlineCompletionsAccessibilityVerbose = 147 + recognizeWordLocales = 92, + renameOnType = 93, + renderControlCharacters = 94, + renderFinalNewline = 95, + renderLineHighlight = 96, + renderLineHighlightOnlyWhenFocus = 97, + renderValidationDecorations = 98, + renderWhitespace = 99, + revealHorizontalRightPadding = 100, + roundedSelection = 101, + rulers = 102, + scrollbar = 103, + scrollBeyondLastColumn = 104, + scrollBeyondLastLine = 105, + scrollPredominantAxis = 106, + selectionClipboard = 107, + selectionHighlight = 108, + selectOnLineNumbers = 109, + showFoldingControls = 110, + showUnused = 111, + snippetSuggestions = 112, + smartSelect = 113, + smoothScrolling = 114, + stickyScroll = 115, + stickyTabStops = 116, + stopRenderingLineAfter = 117, + suggest = 118, + suggestFontSize = 119, + suggestLineHeight = 120, + suggestOnTriggerCharacters = 121, + suggestSelection = 122, + tabCompletion = 123, + tabIndex = 124, + unicodeHighlighting = 125, + unusualLineTerminators = 126, + useShadowDOM = 127, + useTabStops = 128, + wordBreak = 129, + wordSeparators = 130, + wordWrap = 131, + wordWrapBreakAfterCharacters = 132, + wordWrapBreakBeforeCharacters = 133, + wordWrapColumn = 134, + wordWrapOverride1 = 135, + wordWrapOverride2 = 136, + wrappingIndent = 137, + wrappingStrategy = 138, + showDeprecated = 139, + inlayHints = 140, + editorClassName = 141, + pixelRatio = 142, + tabFocusMode = 143, + layoutInfo = 144, + wrappingInfo = 145, + defaultColorDecorators = 146, + colorDecoratorsActivatedOn = 147, + inlineCompletionsAccessibilityVerbose = 148 } export const EditorOptions: { @@ -5025,6 +5033,7 @@ declare namespace monaco.editor { quickSuggestionsDelay: IEditorOption; readOnly: IEditorOption; readOnlyMessage: IEditorOption; + recognizeWordLocales: IEditorOption; renameOnType: IEditorOption; renderControlCharacters: IEditorOption; renderFinalNewline: IEditorOption;