简体   繁体   中英

Making Vim mappings quiet

I have a mapping that I use to print the highlighting on a line. I got the idea from other posters here so thanks for that. Here's what I do:

function! PrintSyntaxItem()
    let l:colorsyntax = synIDattr(synID(line("."), col("."), 0), "name")
    execute "highlight" l:colorsyntax
endfunction

and I map it like this:

nnoremap <A-s> :call PrintSyntaxItem()<CR>

However when I execute it, I get the command line echoed as well as the output that I want which leads to getting a "Press ENTER" prompt. Ie in the output I see:

:execute "highlight" synIDattr(synID(line("."), col("."), 0), "name")
vimBracket     xxx links to Delimiter
Press ENTER or type command to continue

I'd like to lose the :execute line and then the Press ENTER line would go away as well. Is there any way to do this? If I put silent in front of the execute I still get that line printed out but lose the highlight output (as well as the Press ENTER prompt), but then to get back my desired output I just prefix it with unsilent and I get it but...

Basically I want to either suppress the echo of the :execute line or clear it after the fact but I'm not sure how to do either and trawling the docs for info on manipulating the messages hasn't borne any fruit.

Thanks.

It's not the command that you should silence but, as you wrote in the title of your question, the mapping itself:

nnoremap <silent> <A-s> :call PrintSyntaxItem()<CR>

That said, the execute command looks like it can't be silenced easily. I'll look into that.

edit

I've tried all the tricks I could find, including :redir => and a dozen of combinations of [<]silent[>] but I couldn't obtain the desired result. Either I get the prompt or I don't get anything. I'm terribly sorry!

The press enter prompt comes up because the output of highlight takes up multiple lines. You could get rid of the extra line by redirecting the output, removing \\n , and then echoing it:

function! PrintSyntaxItem()
    let l:output = ''
    redir => l:output
    silent exec "hi" synIDattr(synID(line("."), col("."), 0), "name")
    redir END
    echo substitute(l:output, '\n', '', '')
endfunction

However, the xxx sample is no longer properly highlighted. Instead, you can hack the press enter prompt away by temporarily changing cmdheight :

nnoremap <silent> <A-s> :set ch=2 \| exec "hi"
    \ synIDattr(synID(line("."), col("."), 0), "name") \| set ch=1<CR>

This prevents the prompt from being printed in the first place by initially changing the command line height to 2, and then reverting it to 1 afterward in order to cut off the empty line. I did away with the function altogether, but you can of course call it between the set ch if you prefer.

Rather than fudging with the command-line height, how about highlighting the entire line instead of just the xxx part?

function! ShowSyntaxItem()
    redir => l:output
    silent exec "hi" synIDattr(synID(line("."), col("."), 0), "name")
    redir END
    let l:parts = matchlist(output, '\v\n@<=(\S+)(.*$)')
    if (len(l:parts) >= 3)
      redraw | exec "echohl ".l:parts[1] | exec "echo '".l:parts[0]."'" | echohl None
    endif
endfunction

nnoremap <silent> <Leader>as :call PrintSyntaxItem()<CR>

Note, there's no need to declare l:output or re-init it if it exists before the redir as stated in :he redir . This is pretty handy, and shall be going into ye olde vimrc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM