How to make the zsh “correct” functionality remember the spell-correction decisions

aliasautocorrectionspell-checkingzsh

I have enabled correction (I wouldn't call it autocorrection specifically because of this issue) in zsh by enabling setopt correct in my .zshrc.

Now, when I type dtae in a terminal, I get:

dtae        
zsh: correct 'dtae' to 'date' [nyae]? y
Tue Mar 31 11:39:31 CEST 2015

At this point I would like zsh to remember my decision. So the next time I type dtae it should automatically correct to date [1]. However, this does not happen, and zsh is again asking me what to do:

dtae
zsh: correct 'dtae' to 'date' [nyae]?

[1] Unless, of course, if at that time there exists an actual dtae command or alias.

Update:

I have managed to modify the zsh source code (file utils.c, function spckword) to create a custom file containing the aliases automatically created with the invocation of zsh's "correct" functionality:

original:

if (x == 'y' || x == ' ' || x == '\t') 
{
    *s = dupstring(best);
    if (hist)
    hwrep(best);
}

modified:

if (x == 'y' || x == ' ' || x == '\t')
{
    char *aliaspath = getenv("HOME");
    strcat(aliaspath, "/.zsh_correct_aliases");
    FILE *out = fopen(aliaspath, "ab+");
    fprintf(out, "alias %s=\'", *s);
    *s = dupstring(best);
    fprintf(out, "%s\'\n", *s);
    fclose(out);
    if (hist)
    hwrep(best);
}

Upon executing dtae, the following line is added to the file ~/.zsh_correct_aliases:

alias dtae='date'

However, I don't know how to source the newly modified ~/.zsh_correct_aliases file in-place.

Best Answer

You could base your code on the built-in alias defined here

HashTable ht = aliastab;
ht->addnode(ht, ztrdup(wrong_value),
            createaliasnode(ztrdup(right_value), 0));

(not tested)

And add source ~/.zsh_correct_aliases to you .zshrc


EDIT: tested with source:

char *aliaspath = getenv("HOME");
strcat(aliaspath, "/.zsh_correct_aliases");

FILE *out = fopen(aliaspath, "ab+");
fprintf(out, "alias %s=\'", *s);

HashTable ht = aliastab;
ht->addnode(ht, ztrdup(*s),
    createaliasnode(ztrdup(best), 0));

*s = dupstring(best);
fprintf(out, "%s\'\n", *s);
fclose(out);
if (hist)
    hwrep(best);

It gives:

$ setopt correct 
$ dtea    
zsh: correct 'dtea' to 'date' [nyae]? y
lun. janv.  8 01:03:55 CET 2018  
$ alias  
dtea=date
$ dtea    
lun. janv.  8 01:07:42 CET 2018