mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-06-13 07:10:26 +08:00
106 lines
3.5 KiB
TypeScript
106 lines
3.5 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
'use strict';
|
|
|
|
import { Position, TextDocument } from 'vscode';
|
|
|
|
export enum CharacterClass {
|
|
REGULAR = 0,
|
|
WORD_SEPARATOR = 1,
|
|
WHITESPACE = 2
|
|
}
|
|
|
|
export enum WordType {
|
|
NONE = 0,
|
|
SEPARATOR = 1,
|
|
REGULAR = 2
|
|
}
|
|
|
|
export type WordCharacters = CharacterClass[];
|
|
|
|
export interface IWord {
|
|
start: number;
|
|
end: number;
|
|
wordType: WordType;
|
|
}
|
|
|
|
export class Words {
|
|
|
|
public static createWordCharacters(wordSeparators: string): WordCharacters {
|
|
let result: CharacterClass[] = [];
|
|
|
|
// Make array fast for ASCII text
|
|
for (var chCode = 0; chCode < 256; chCode++) {
|
|
result[chCode] = CharacterClass.REGULAR;
|
|
}
|
|
|
|
for (var i = 0, len = wordSeparators.length; i < len; i++) {
|
|
result[wordSeparators.charCodeAt(i)] = CharacterClass.WORD_SEPARATOR;
|
|
}
|
|
|
|
result[' '.charCodeAt(0)] = CharacterClass.WHITESPACE;
|
|
result['\t'.charCodeAt(0)] = CharacterClass.WHITESPACE;
|
|
|
|
return result;
|
|
}
|
|
|
|
public static findNextWord(doc: TextDocument, pos: Position, wordCharacterClass: WordCharacters): IWord {
|
|
|
|
let lineContent = doc.lineAt(pos.line).text;
|
|
let wordType = WordType.NONE;
|
|
let len = lineContent.length;
|
|
|
|
for (let chIndex = pos.character; chIndex < len; chIndex++) {
|
|
let chCode = lineContent.charCodeAt(chIndex);
|
|
let chClass = (wordCharacterClass[chCode] || CharacterClass.REGULAR);
|
|
|
|
if (chClass === CharacterClass.REGULAR) {
|
|
if (wordType === WordType.SEPARATOR) {
|
|
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordCharacterClass, wordType, chIndex - 1), chIndex);
|
|
}
|
|
wordType = WordType.REGULAR;
|
|
} else if (chClass === CharacterClass.WORD_SEPARATOR) {
|
|
if (wordType === WordType.REGULAR) {
|
|
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordCharacterClass, wordType, chIndex - 1), chIndex);
|
|
}
|
|
wordType = WordType.SEPARATOR;
|
|
} else if (chClass === CharacterClass.WHITESPACE) {
|
|
if (wordType !== WordType.NONE) {
|
|
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordCharacterClass, wordType, chIndex - 1), chIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (wordType !== WordType.NONE) {
|
|
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordCharacterClass, wordType, len - 1), len);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static _findStartOfWord(lineContent: string, wordCharacterClass: WordCharacters, wordType: WordType, startIndex: number): number {
|
|
for (let chIndex = startIndex; chIndex >= 0; chIndex--) {
|
|
let chCode = lineContent.charCodeAt(chIndex);
|
|
let chClass = (wordCharacterClass[chCode] || CharacterClass.REGULAR);
|
|
|
|
if (chClass === CharacterClass.WHITESPACE) {
|
|
return chIndex + 1;
|
|
}
|
|
if (wordType === WordType.REGULAR && chClass === CharacterClass.WORD_SEPARATOR) {
|
|
return chIndex + 1;
|
|
}
|
|
if (wordType === WordType.SEPARATOR && chClass === CharacterClass.REGULAR) {
|
|
return chIndex + 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
private static _createWord(lineContent: string, wordType: WordType, start: number, end: number): IWord {
|
|
// console.log('WORD ==> ' + start + ' => ' + end + ':::: <<<' + lineContent.substring(start, end) + '>>>');
|
|
return { start: start, end: end, wordType: wordType };
|
|
}
|
|
}
|