Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/expandBraces.ts
Original file line number Diff line number Diff line change
@@ -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 = {};
Expand Down
18 changes: 16 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -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) {
Expand Down
15 changes: 15 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[]>('dictionary', [
Expand All @@ -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(
Expand All @@ -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
Expand Down