diff --git a/src/expandBraces.ts b/src/expandBraces.ts index 482dd2f..fe50af9 100644 --- a/src/expandBraces.ts +++ b/src/expandBraces.ts @@ -1,5 +1,8 @@ import { DictionaryWords } from "./types/Dictionary"; +/** + * Expands the vim-abolish style multiple-word-ending specifications into distinct pairs + */ export default function expandBraces(dict: DictionaryWords): DictionaryWords { let redo = 0; let newDict: DictionaryWords = {}; diff --git a/src/extension.ts b/src/extension.ts index 72773c6..b80bb42 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,6 +6,9 @@ let config: WorkspaceConfiguration; let words: DictionaryWords; // let triggers: string[]; +/** + * Initialize this extension. + */ export function activate(_context: ExtensionContext) { config = getConfig(); words = getWords(config); @@ -28,12 +31,21 @@ export function activate(_context: ExtensionContext) { // this method is called when your extension is deactivated export function deactivate() {} +/** + * Check to see if we've reached the end of a "word" and, if so, + * see if the word is in the list of common typos (dict key) and, + * if so, fix it. + */ function correctTheWord(event: TextDocumentChangeEvent): void { if (!event.contentChanges.length) { + // the event was fired with no physical changes (e.g. the dirty flag was set directly) return; } + // TODO Under what circumstances might there be more than one change? Do we need to handle that scenario? + if (!!event.contentChanges[0].text.match(/[A-Za-z]/)) { + // The new text is a single letter, meaning the user is still typing a word return; } @@ -45,11 +57,13 @@ function correctTheWord(event: TextDocumentChangeEvent): void { const { selection } = editor; const originalPosition = selection.start.translate(0, 1); const startPos = new Position(0, 0); + + // Here, we get all of the document text leading up to the current cursor location + // and then find the biggest last portion that matches letters and special symbols + // TODO It might be more efficient to only grab the text from the start of the current line (i.e. editor.document.lineAt(position)) const text = editor.document.getText( new Range(startPos, originalPosition) ); - - // matches letters and special letters const lastWord = getLastWord(text); // if (triggers.length) { diff --git a/src/helpers.ts b/src/helpers.ts index 60e6442..c4f0736 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -3,6 +3,9 @@ import { DictionaryWords, Dictionary } from './types/Dictionary'; import * as largeList from './defaultList.json'; import expandBraces from './expandBraces'; +/** + * Loads up the pairs of corrections to check (that are pertinent for the current context) + */ export function getWords(config: WorkspaceConfiguration) { const editor = window.activeTextEditor; const dictionary = config.get('dictionary', [ @@ -29,6 +32,9 @@ export function getWords(config: WorkspaceConfiguration) { return expandBraces(words); } +/** + * Pulls the "auto-correct" section out of the VSCode configuration + */ export function getConfig(): WorkspaceConfiguration { const editor = window.activeTextEditor; const config = workspace.getConfiguration( @@ -38,7 +44,16 @@ export function getConfig(): WorkspaceConfiguration { return config; } +/** + * Retrieves the last "word" from the given inputText. + * A "word" is any string of letters and/or certain special symbols, + * optionally followed by one non-alphanumeric. + * (The returned word does not include the trailing non-alphanumeric.) + */ export function getLastWord(inputText: string): string | undefined { + // \p{L} matches anything letter-ish + // \w (lowercase w) matches any alphanumeric [A-Za-z0-9_] + // \W (uppercase W) matches anything except an alphanumeric [A-Za-z0-9_] const re = /((\p{L}|[><=+.,;@*()?!#$€%§&_'"\/\\-])+)[-_><\W]?$/gu; const match = re.exec(inputText); return match && match.length > 1 ? match[1] : undefined