2

Is it possible to check if a normal mapping/command is being typed?

That's also when the showcmd setting takes effect.

I can't seem to find anything about this in the doc, no autocmd-event nor related functions.

The idea would be to make it more obvious that Vim is waiting for more input by, for example, changing the cursorline color.

5
  • I don't think so. Why do you need this? Jun 18 '20 at 6:34
  • To see what which triggers are available to execute something automatically you can read :h autocmd-events. There you will see that there is no event which triggers when you are typing in normal mode. However Christian's question is interesting: Maybe there is another way to do what you want and you are just asking the wrong question (See what is the xy problem)
    – statox
    Jun 18 '20 at 7:01
  • 1
    You mention 'showcmd' so that suggests your requirement is more specific than looking for typing. Are you looking for the case of pending commands? (E.g. user hits Normal mode f but hasn't yet hit the target character.) There is an autocmd event related to this: SafeState...but it's the inverse of what you want. That is, it triggers under many circumstances but explicitly NOT when a command is pending. Maybe you can figure out a way to leverage that. Probably a long shot but doesn't hurt to throw it out there.
    – B Layer
    Jun 18 '20 at 9:31
  • That event requires Vim 8.2, FYI (just noticed).
    – B Layer
    Jun 18 '20 at 9:35
  • Thanks for all your comments. I should have told what I try to achieve, I edited the post. Safestate is indeed the exact invert of what I'd need!
    – Biggybi
    Jun 18 '20 at 11:20
3

The idea would be to make it more obvious that Vim is waiting for more input by, for example, changing the cursorline color.

You could try to leverage the fact that when a mapping is being executed, the output of state() should contain the m flag, and in operator-pending mode it should contain the o flag:

set showcmd
set timeout ttimeout timeoutlen=3000 ttimeoutlen=100
call timer_start(10, 'Func', #{repeat: -1})
fu Func(_) abort
    if state() =~# '[mo]'
        setl cul
    else
        setl nocul
    endif
endfu

Try it like this:

vim -Nu NONE -S <(cat <<'EOF'
    set showcmd
    set timeout ttimeout timeoutlen=3000 ttimeoutlen=100
    call timer_start(10, 'Func', #{repeat: -1})
    fu Func(_) abort
        if state() =~# '[mo]'
            setl cul
        else
            setl nocul
        endif
    endfu
    call setline(1, ['foo', 'bar', 'baz'])
EOF
)

Press y to invoke the yank operator: you should see the current line being underlined. Press y again to yank the line: you should see that the current line is no longer being underlined.

No idea how reliable it is. If the code has a negative impact performance-wise, increase the waiting time in the timer:

call timer_start(10, 'Func', #{repeat: -1})
                 ^^
                 try 50, 100, ...
2

This is an example of a working solution based on user938271's answer.

It switches the colors of a group between the default and our selection.
The autocommand reloads the globals when a new theme is applied.
I also made sure to restrict the function to normal mode only.

augroup SaveGroupColors
  au!
  au ColorScheme *
        \ let g:save_fg = synIDattr(hlID(g:hl_group_save), "fg#")
        \ | let g:save_bg = synIDattr(hlID(g:hl_group_save), "bg#")
augroup end

let g:hl_group_save = "CursorLineNr"
let g:save_fg = synIDattr(hlID(g:hl_group_save), "fg#")
let g:save_bg = synIDattr(hlID(g:hl_group_save), "bg#")
let g:change_fg = "#383a42"
let g:change_bg = "#e06c75"

call timer_start(10, 'PendingCommandMode', #{repeat: -1})
function! PendingCommandMode(_) abort
  if mode() == 'n' && state() =~# '\C[mo]'
    exe "hi" g:hl_group_save "guifg=".g:change_fg "guibg=".g:change_bg
  else
    exe "hi" g:hl_group_save "guifg=" . g:save_fg "guibg=" . g:save_bg
  endif
endfunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.