Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "z=" in a mapping

Tags:

vim

If I use <Esc>[s1z=`]a in an inoremap mapping (jump to normal mode, find previous spelling error, replace it with the first choice, jump back to last edit and append), everything works fine. The problem is I often don't want the first spelling choice. If I remove the 1 I will be given the spelling menu, but the `]a seems to get swallowed up and lands me at the first character of the corrected word still in normal mode. The mapping itself shouldn't be looking for input, perse, as the z= itself should handle the menu entry. Indeed if I run these commands manually (without the 1, it works as expected. I have tried making named marks and jumping back to those, but it seems z= and everything after it gets consumed as one thing. Does anyone have any suggestion as to how to make the mapping continue after I make a spelling menu selection? Thanks.

like image 624
linux_sa Avatar asked Apr 17 '26 04:04

linux_sa


1 Answers

I think that Vim stops processing the right-hand side of the mapping as soon as it presses z= because it's not a complete command (you have to provide the index of a suggestion in the menu for it to be complete). The :normal command has the same issue:

:norm[al][!] {commands}

...

{commands} should be a complete command. If {commands} does not finish a command, the last one will be aborted as if <Esc> or <C-C> was typed.

As an alternative, you could invoke the feedkeys() function to press z=. For example:

ino <c-j> <c-r>=<sid>fix_typo()<cr>

fu! s:fix_typo() abort
    let spell_save = &l:spell
    try
        setl spell
        call feedkeys("\e\e[sz=", 'int')
        augroup fix_typo
            au!
            au TextChanged * call feedkeys('`]a', 'int')
                \ | exe 'au! fix_typo'
                \ | aug! fix_typo
        augroup END
    finally
        call timer_start(0, {-> execute('let &l:spell = '.spell_save)})
    endtry
    return ''
endfu

This code installs a mapping in insert mode using the C-j key. You could use another key if you don't like this one.

The mapping calls the s:fix_typo() function which:

  • temporarily enables 'spell' to avoid the error E756
  • presses the keys Esc Esc [s z= to prompt the suggestions
  • installs a fire-once autocmd listening to TextChanged to press the keys `]a once you've selected a word in the menu
  • restores the original value of 'spell'
like image 61
user938271 Avatar answered Apr 21 '26 02:04

user938271