Pretter for each ts file

This commit is contained in:
Pine Wu
2018-10-10 09:37:51 -07:00
parent c945fe9288
commit 23674b2cfe
55 changed files with 1755 additions and 1479 deletions

View File

@ -14,9 +14,9 @@ export enum Mode {
}
export interface ModifierKeys {
ctrl?: boolean,
alt?: boolean,
shifit?: boolean
ctrl?: boolean;
alt?: boolean;
shifit?: boolean;
}
export class DeleteRegister {
@ -42,12 +42,10 @@ export interface IController {
}
export abstract class AbstractCommandDescriptor {
public abstract createCommand(args?: any): Command;
}
export interface Command {
commandId: string,
args?: any[]
commandId: string;
args?: any[];
}

View File

@ -4,15 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {
TextEditorCursorStyle,
Position,
Range,
Selection,
TextEditor,
TextEditorRevealType,
window
} from 'vscode';
import { TextEditorCursorStyle, Position, Range, Selection, TextEditor, TextEditorRevealType, window } from 'vscode';
import { Words } from './words';
import { MotionState, Motion } from './motions';
@ -25,19 +17,28 @@ export interface ITypeResult {
}
export class Controller implements IController {
private _currentMode: Mode;
private _currentInput: string;
private _motionState: MotionState;
private _isVisual: boolean;
public get motionState(): MotionState { return this._motionState; }
public findMotion(input: string): Motion { return Mappings.findMotion(input); }
public isMotionPrefix(input: string): boolean { return Mappings.isMotionPrefix(input); }
public get motionState(): MotionState {
return this._motionState;
}
public findMotion(input: string): Motion {
return Mappings.findMotion(input);
}
public isMotionPrefix(input: string): boolean {
return Mappings.isMotionPrefix(input);
}
private _deleteRegister: DeleteRegister;
public setDeleteRegister(register: DeleteRegister): void { this._deleteRegister = register; }
public getDeleteRegister(): DeleteRegister { return this._deleteRegister; }
public setDeleteRegister(register: DeleteRegister): void {
this._deleteRegister = register;
}
public getDeleteRegister(): DeleteRegister {
return this._deleteRegister;
}
constructor() {
this._motionState = new MotionState();
@ -180,11 +181,13 @@ export class Controller implements IController {
if (this._currentMode === Mode.REPLACE) {
let pos = editor.selection.active;
editor.edit((builder) => {
builder.replace(new Range(pos.line, pos.character, pos.line, pos.character + 1), text);
}).then(() => {
setPositionAndReveal(editor, pos.line, pos.character + 1);
});
editor
.edit(builder => {
builder.replace(new Range(pos.line, pos.character, pos.line, pos.character + 1), text);
})
.then(() => {
setPositionAndReveal(editor, pos.line, pos.character + 1);
});
return Promise.resolve({
hasConsumedInput: true,
@ -207,7 +210,7 @@ export class Controller implements IController {
if (this._currentMode === Mode.REPLACE) {
let pos = editor.selection.active;
editor.edit((builder) => {
editor.edit(builder => {
builder.replace(new Range(pos.line, pos.character - replaceCharCnt, pos.line, pos.character), text);
});
@ -219,7 +222,7 @@ export class Controller implements IController {
private _interpretNormalModeInput(editor: TextEditor, modifierKeys: ModifierKeys): Thenable<ITypeResult> {
if (this._currentInput.startsWith(':')) {
return window.showInputBox({ value: 'tabm' }).then((value) => {
return window.showInputBox({ value: 'tabm' }).then(value => {
return this._findMapping(value || '', editor, modifierKeys);
});
}

View File

@ -18,7 +18,7 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand(commandId, run));
}
function registerCtrlKeyBinding(key: string): void {
registerCommandNice(key, function (args) {
registerCommandNice(key, function(args) {
if (!vscode.window.activeTextEditor) {
return;
}
@ -28,34 +28,34 @@ export function activate(context: vscode.ExtensionContext) {
let vimExt = new VimExt();
registerCommandNice('type', function (args) {
registerCommandNice('type', function(args) {
if (!vscode.window.activeTextEditor) {
return;
}
vimExt.type(args.text);
});
registerCommandNice('replacePreviousChar', function (args) {
registerCommandNice('replacePreviousChar', function(args) {
if (!vscode.window.activeTextEditor) {
return;
}
vimExt.replacePrevChar(args.text, args.replaceCharCnt);
});
registerCommandNice('compositionStart', function (args) {
registerCommandNice('compositionStart', function(args) {
if (!vscode.window.activeTextEditor) {
return;
}
vimExt.compositionStart();
});
registerCommandNice('compositionEnd', function (args) {
registerCommandNice('compositionEnd', function(args) {
if (!vscode.window.activeTextEditor) {
return;
}
vimExt.compositionEnd();
});
registerCommandNice('vim.goToNormalMode', function (args) {
registerCommandNice('vim.goToNormalMode', function(args) {
vimExt.goToNormalMode();
});
registerCommandNice('vim.clearInput', function (args) {
registerCommandNice('vim.clearInput', function(args) {
vimExt.clearInput();
});
// registerCommandNice('paste', function(args) {
@ -84,7 +84,6 @@ function getConfiguredWordSeparators(): string {
}
class VimExt {
private _inNormalMode: ContextKey;
private _hasInput: ContextKey;
private _statusBar: StatusBar;
@ -95,16 +94,16 @@ class VimExt {
this._hasInput = new ContextKey('vim.hasInput');
this._statusBar = new StatusBar();
this._controller = new Controller()
this._controller = new Controller();
vscode.window.onDidChangeActiveTextEditor((textEditor) => {
vscode.window.onDidChangeActiveTextEditor(textEditor => {
if (!textEditor) {
return;
}
this._ensureState();
});
vscode.window.onDidChangeTextEditorSelection((e) => {
vscode.window.onDidChangeTextEditorSelection(e => {
let isVisual = this._controller.getVisual();
if (!isVisual) {
@ -154,7 +153,7 @@ class VimExt {
}
public type(text: string, modifierKeys: ModifierKeys = { ctrl: false, shifit: false, alt: false }): void {
this._controller.type(vscode.window.activeTextEditor, text, modifierKeys).then((r) => {
this._controller.type(vscode.window.activeTextEditor, text, modifierKeys).then(r => {
if (r.hasConsumedInput) {
this._ensureState();
if (r.executeEditorCommand) {
@ -186,7 +185,7 @@ class VimExt {
}
public compositionEnd(): void {
this._controller.compositionEnd(vscode.window.activeTextEditor).then((r) => {
this._controller.compositionEnd(vscode.window.activeTextEditor).then(r => {
if (r.hasConsumedInput) {
this._ensureState();
if (r.executeEditorCommand) {

View File

@ -9,43 +9,47 @@ import { Motion, Motions } from './motions';
import { Operator, Operators } from './operators';
import { IController, Command, AbstractCommandDescriptor, ModifierKeys } from './common';
const CHAR_TO_BINDING: { [char: string]: any; } = {};
const CHAR_TO_BINDING: { [char: string]: any } = {};
function defineBinding(char: string, value: any, modifierKeys: ModifierKeys): void {
let key = modifierKeys.ctrl ? 'CTRL + ' + char : char;
CHAR_TO_BINDING[key] = value;
};
}
function getBinding(char: string, modifierKeys: ModifierKeys): any {
let key = modifierKeys.ctrl ? 'CTRL + ' + char : char;
return CHAR_TO_BINDING[key];
};
}
function defineOperator(char: string, operator: Operator, modifierKeys: ModifierKeys = {}): void {
defineBinding(char + '__operator__', operator, modifierKeys);
};
}
function getOperator(char: string, modifierKeys: ModifierKeys = {}): Operator {
return getBinding(char + '__operator__', modifierKeys);
};
}
function defineCommand(char: string, commandId: string, modifierKeys: ModifierKeys = {}): void {
defineBinding(char + '__command__', { commandId: commandId }, modifierKeys);
};
}
function getCommand(char: string, modifierKeys: ModifierKeys = {}): Command {
return getBinding(char + '__command__', modifierKeys);
};
}
function defineMotion(char: string, motion: Motion, modifierKeys: ModifierKeys = {}): void {
defineBinding(char + '__motion__', motion, modifierKeys);
};
}
function getMotion(char: string, modifierKeys: ModifierKeys = {}): Motion {
return getBinding(char + '__motion__', modifierKeys);
};
}
function defineMotionCommand(char: string, motionCommand: AbstractCommandDescriptor, modifierKeys: ModifierKeys = {}): void {
function defineMotionCommand(
char: string,
motionCommand: AbstractCommandDescriptor,
modifierKeys: ModifierKeys = {}
): void {
defineBinding(char + '__motioncommand__', motionCommand, modifierKeys);
};
}
function getMotionCommand(char: string, modifierKeys: ModifierKeys = {}): AbstractCommandDescriptor {
return getBinding(char + '__motioncommand__', modifierKeys);
};
}
// Operators
defineOperator('x', Operators.DeleteCharUnderCursor);
@ -120,14 +124,12 @@ defineMotionCommand('zb', Motions.RevealCurrentLineAtBottom);
defineMotionCommand('zc', Motions.FoldUnder);
defineMotionCommand('zo', Motions.UnfoldUnder);
export interface IFoundOperator {
runNormal(controller: IController, editor: TextEditor): boolean;
runVisual(controller: IController, editor: TextEditor): boolean;
}
export class Mappings {
public static findMotion(input: string): Motion {
let parsed = _parseNumberAndString(input);
let motion = getMotion(parsed.input.substr(0, 1));
@ -150,7 +152,11 @@ export class Mappings {
return command;
}
private static findMotionCommandFromNumberAndString(numberAndString: INumberAndString, isVisual: boolean, modifierKeys: ModifierKeys): Command {
private static findMotionCommandFromNumberAndString(
numberAndString: INumberAndString,
isVisual: boolean,
modifierKeys: ModifierKeys
): Command {
let motionCommand = getMotionCommand(numberAndString.input.substr(0, 1), modifierKeys);
if (!motionCommand) {
motionCommand = getMotionCommand(numberAndString.input.substr(0, 2), modifierKeys);
@ -164,7 +170,12 @@ export class Mappings {
if (!motionCommand) {
motionCommand = getMotionCommand(numberAndString.input, modifierKeys);
}
return motionCommand ? motionCommand.createCommand({ isVisual: isVisual, repeat: numberAndString.hasRepeatCount ? numberAndString.repeatCount : undefined }) : null;
return motionCommand
? motionCommand.createCommand({
isVisual: isVisual,
repeat: numberAndString.hasRepeatCount ? numberAndString.repeatCount : undefined
})
: null;
}
public static findOperator(input: string, modifierKeys: ModifierKeys): IFoundOperator {
@ -223,7 +234,7 @@ function _parseNumberAndString(input: string, numberAtBeginning: boolean = true)
hasRepeatCount: false,
repeatCount: 1,
input: input
}
};
}
interface INumberAndString {

View File

@ -9,7 +9,6 @@ import { Words, WordCharacters } from './words';
import { Command, AbstractCommandDescriptor } from './common';
export class MotionState {
public anchor: Position;
public cursorDesiredCharacter: number;
public wordCharacterClass: WordCharacters;
@ -19,7 +18,6 @@ export class MotionState {
this.wordCharacterClass = null;
this.anchor = null;
}
}
export abstract class Motion {
@ -34,7 +32,6 @@ export abstract class Motion {
}
class RepeatingMotion extends Motion {
private _actual: Motion;
private _repeatCount: number;
@ -56,7 +53,7 @@ class NextCharacterMotion extends Motion {
public run(doc: TextDocument, pos: Position, state: MotionState): Position {
if (pos.character === doc.lineAt(pos.line).text.length) {
// on last character
return ((pos.line + 1 < doc.lineCount) ? new Position(pos.line + 1, 0) : pos);
return pos.line + 1 < doc.lineCount ? new Position(pos.line + 1, 0) : pos;
}
return new Position(pos.line, pos.character + 1);
@ -80,7 +77,7 @@ class DownMotion extends Motion {
public run(doc: TextDocument, pos: Position, state: MotionState): Position {
let line = pos.line;
state.cursorDesiredCharacter = (state.cursorDesiredCharacter === -1 ? pos.character : state.cursorDesiredCharacter);
state.cursorDesiredCharacter = state.cursorDesiredCharacter === -1 ? pos.character : state.cursorDesiredCharacter;
if (line < doc.lineCount - 1) {
line++;
@ -95,7 +92,7 @@ class UpMotion extends Motion {
public run(doc: TextDocument, pos: Position, state: MotionState): Position {
let line = pos.line;
state.cursorDesiredCharacter = (state.cursorDesiredCharacter === -1 ? pos.character : state.cursorDesiredCharacter);
state.cursorDesiredCharacter = state.cursorDesiredCharacter === -1 ? pos.character : state.cursorDesiredCharacter;
if (line > 0) {
line--;
@ -138,7 +135,7 @@ class NextWordStartMotion extends Motion {
if (pos.character >= lineContent.length - 1) {
// cursor at end of line
return ((pos.line + 1 < doc.lineCount) ? new Position(pos.line + 1, 0) : pos);
return pos.line + 1 < doc.lineCount ? new Position(pos.line + 1, 0) : pos;
}
let nextWord = Words.findNextWord(doc, pos, state.wordCharacterClass);
@ -171,7 +168,7 @@ class NextWordEndMotion extends Motion {
if (pos.character >= lineContent.length - 1) {
// no content on this line or cursor at end of line
return ((pos.line + 1 < doc.lineCount) ? new Position(pos.line + 1, 0) : pos);
return pos.line + 1 < doc.lineCount ? new Position(pos.line + 1, 0) : pos;
}
let nextWord = Words.findNextWord(doc, pos, state.wordCharacterClass);
@ -201,7 +198,6 @@ class GoToLineUndefinedMotion extends Motion {
}
abstract class GoToLineMotion extends Motion {
protected firstNonWhitespaceChar(doc: TextDocument, line: number): number {
let lineContent = doc.lineAt(line).text;
let character = 0;
@ -214,7 +210,6 @@ abstract class GoToLineMotion extends Motion {
}
return character;
}
}
class GoToFirstLineMotion extends GoToLineMotion {
@ -245,7 +240,6 @@ class GoToLineDefinedMotion extends GoToLineMotion {
}
class CursorMoveCommand extends AbstractCommandDescriptor {
constructor(private to: string, private by?: string) {
super();
}
@ -256,7 +250,7 @@ class CursorMoveCommand extends AbstractCommandDescriptor {
by: this.by,
value: args.repeat || 1,
select: !!args.isVisual
}
};
return {
commandId: 'cursorMove',
args: cursorMoveArgs
@ -265,7 +259,6 @@ class CursorMoveCommand extends AbstractCommandDescriptor {
}
class EditorScrollCommand extends AbstractCommandDescriptor {
constructor(private to: string, private by?: string) {
super();
}
@ -276,7 +269,7 @@ class EditorScrollCommand extends AbstractCommandDescriptor {
by: this.by,
value: args.repeat || 1,
revealCursor: true
}
};
return {
commandId: 'editorScroll',
args: editorScrollArgs
@ -285,7 +278,6 @@ class EditorScrollCommand extends AbstractCommandDescriptor {
}
class RevealCurrentLineCommand extends AbstractCommandDescriptor {
constructor(private at: string) {
super();
}
@ -304,7 +296,6 @@ class RevealCurrentLineCommand extends AbstractCommandDescriptor {
}
class MoveActiveEditorCommandByPosition extends AbstractCommandDescriptor {
constructor() {
super();
}
@ -313,7 +304,7 @@ class MoveActiveEditorCommandByPosition extends AbstractCommandDescriptor {
let moveActiveEditorArgs: any = {
to: args.repeat === void 0 ? 'last' : 'position',
value: args.repeat !== void 0 ? args.repeat + 1 : undefined
}
};
return {
commandId: 'moveActiveEditor',
args: moveActiveEditorArgs
@ -322,7 +313,6 @@ class MoveActiveEditorCommandByPosition extends AbstractCommandDescriptor {
}
class MoveActiveEditorCommand extends AbstractCommandDescriptor {
constructor(private to: string) {
super();
}
@ -331,7 +321,7 @@ class MoveActiveEditorCommand extends AbstractCommandDescriptor {
let moveActiveEditorArgs: any = {
to: this.to,
value: args.repeat ? args.repeat : 1
}
};
return {
commandId: 'moveActiveEditor',
args: moveActiveEditorArgs
@ -339,7 +329,6 @@ class MoveActiveEditorCommand extends AbstractCommandDescriptor {
}
}
class FoldCommand extends AbstractCommandDescriptor {
constructor() {
super();
}
@ -348,7 +337,7 @@ class FoldCommand extends AbstractCommandDescriptor {
let foldEditorArgs: any = {
levels: args.repeat ? args.repeat : 1,
direction: 'up'
}
};
return {
commandId: 'editor.fold',
args: foldEditorArgs
@ -357,7 +346,6 @@ class FoldCommand extends AbstractCommandDescriptor {
}
class UnfoldCommand extends AbstractCommandDescriptor {
constructor() {
super();
}
@ -366,7 +354,7 @@ class UnfoldCommand extends AbstractCommandDescriptor {
let foldEditorArgs: any = {
levels: args.repeat ? args.repeat : 1,
direction: 'up'
}
};
return {
commandId: 'editor.unfold',
args: foldEditorArgs

View File

@ -9,7 +9,6 @@ import { MotionState, Motion, Motions } from './motions';
import { Mode, IController, DeleteRegister } from './common';
export abstract class Operator {
public abstract runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean;
public abstract runVisualMode(ctrl: IController, ed: TextEditor, args: string): boolean;
@ -32,7 +31,7 @@ export abstract class Operator {
protected delete(ctrl: IController, ed: TextEditor, isWholeLine: boolean, range: Range): void {
ctrl.setDeleteRegister(new DeleteRegister(isWholeLine, ed.document.getText(range)));
ed.edit((builder) => {
ed.edit(builder => {
builder.delete(range);
});
}
@ -81,7 +80,11 @@ class VisualOperator extends OperatorWithNoArgs {
class DeleteCharUnderCursorOperator extends Operator {
public runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean {
let to = Motions.NextCharacter.repeat(repeatCount > 1, repeatCount).run(this.doc(ed), this.pos(ed), ctrl.motionState);
let to = Motions.NextCharacter.repeat(repeatCount > 1, repeatCount).run(
this.doc(ed),
this.pos(ed),
ctrl.motionState
);
let from = this.pos(ed);
this.delete(ctrl, ed, false, new Range(from.line, from.character, to.line, to.character));
@ -134,7 +137,6 @@ abstract class OperatorWithMotion extends Operator {
public runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean {
let motion = ctrl.findMotion(args);
if (!motion) {
// is it motion building
if (ctrl.isMotionPrefix(args)) {
return false;
@ -151,7 +153,6 @@ abstract class OperatorWithMotion extends Operator {
}
class DeleteToOperator extends OperatorWithMotion {
public runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean {
if (args === 'd') {
// dd
@ -177,7 +178,6 @@ class DeleteToOperator extends OperatorWithMotion {
}
class PutOperator extends Operator {
public runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean {
let register = ctrl.getDeleteRegister();
if (!register) {
@ -189,7 +189,7 @@ class PutOperator extends Operator {
let pos = this.pos(ed);
if (!register.isWholeLine) {
ed.edit((builder) => {
ed.edit(builder => {
builder.insert(new Position(pos.line, pos.character + 1), str);
});
return true;
@ -206,7 +206,7 @@ class PutOperator extends Operator {
str = '\n' + str;
}
ed.edit((builder) => {
ed.edit(builder => {
builder.insert(new Position(insertLine, insertCharacter), str);
});
@ -223,7 +223,7 @@ class PutOperator extends Operator {
let str = register.content;
let sel = this.sel(ed);
ed.edit((builder) => {
ed.edit(builder => {
builder.replace(sel, str);
});
@ -232,7 +232,6 @@ class PutOperator extends Operator {
}
class ReplaceOperator extends Operator {
public runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean {
if (args.length === 0) {
// input not ready
@ -247,7 +246,7 @@ class ReplaceOperator extends Operator {
return true;
}
ed.edit((builder) => {
ed.edit(builder => {
builder.replace(new Range(pos.line, pos.character, pos.line, toCharacter), repeatString(args, repeatCount));
});
@ -274,7 +273,7 @@ class ReplaceOperator extends Operator {
}
}
ed.edit((builder) => {
ed.edit(builder => {
builder.replace(sel, dstString);
});
@ -283,7 +282,6 @@ class ReplaceOperator extends Operator {
}
class ReplaceModeOperator extends Operator {
public runNormalMode(ctrl: IController, ed: TextEditor, repeatCount: number, args: string): boolean {
ctrl.setMode(Mode.REPLACE);
return true;
@ -294,11 +292,9 @@ class ReplaceModeOperator extends Operator {
ctrl.setMode(Mode.INSERT);
return true;
}
}
class ChangeOperator extends OperatorWithMotion {
protected _runNormalMode(ctrl: IController, ed: TextEditor, motion: Motion): boolean {
let to = motion.run(this.doc(ed), this.pos(ed), ctrl.motionState);
let from = this.pos(ed);
@ -340,5 +336,5 @@ export const Operators = {
Put: new PutOperator(),
Replace: new ReplaceOperator(),
Change: new ChangeOperator(),
ReplaceMode: new ReplaceModeOperator(),
ReplaceMode: new ReplaceModeOperator()
};

View File

@ -27,7 +27,6 @@ export interface IWord {
}
export class Words {
public static createWordCharacters(wordSeparators: string): WordCharacters {
let result: CharacterClass[] = [];
@ -47,43 +46,67 @@ export class Words {
}
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);
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);
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);
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);
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 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 {
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);
let chClass = wordCharacterClass[chCode] || CharacterClass.REGULAR;
if (chClass === CharacterClass.WHITESPACE) {
return chIndex + 1;