Wikia

Vim Tips Wiki

Make echo seen when it would otherwise disappear and go unseen

Talk0
1,613pages on
this wiki
Revision as of 06:24, July 13, 2012 by JohnBot (Talk | contribs)

Tip 1379 Printable Monobook Previous Next

created 2006 · complexity advanced · author Yakov Lerner · version 6.0


Sometimes echo from a mapping disappears and is not seen (every script writer knows this problem).

This weird trick, PersistentEcho(), echoes messages that will not easily disappear.

This is a really intrusive and weird trick. Please do not use for external scripts (since it modifies &updatetime). For your internal consumption only.

" PersistentEcho() - super-sticky echo message.
" PersistentEcho() echoes message that refuses
" to disappear that simply. This is really weird intrusive trick, but sometimes
" echo from a script disappears unexplainably no matter what other solution I tried.
" Don't use this in external scripts please; this is for your internal uses only.
func! PersistentEcho(msg)
  echo a:msg
  let g:PersistentEcho=a:msg
endfun
let g:PersistentEcho=''
if &ut>200|let &ut=200|endif
au CursorHold * if PersistentEcho!=''|echo PersistentEcho|let PersistentEcho=''|endif

Comments

Would :echom by definition be a persistent echo?


No. echom results in a longer-term message that can be recalled on demand; however, the user would need to know to type :messages to see it.


" The following is a self destructive version of the
" CursorHold autocmd. It also restores 'updatetime'.
let s:Pecho=''
fu! s:Pecho(msg)
  if &ut!=11|let s:hold_ut=&ut|let &ut=11|en
  let s:Pecho=a:msg
  aug Pecho
    au CursorHold * if s:Pecho!=''|echo s:Pecho
          \|let s:Pecho=''|let &ut=s:hold_ut|en
        \|aug Pecho|exe 'au!'|aug END|aug! Pecho
  aug END
endf

" Test of above
au! BufEnter foo call s:Pecho("Entered foo")

" Now even changing to "foo" in a different tab page
" will print the message.

" further improvement in restoration of the &updatetime. To make this
" usable in the plugins, we want it to be safe for the case when
" two plugins use same this same technique. Two independent
" restorations of &ut can run in unpredictable sequence. In order to
" make it safe, we add additional check in &ut restoration.
let s:Pecho=''
fu! s:Pecho(msg)
  let s:hold_ut=&ut | if &ut>1|let &ut=1|en
  let s:Pecho=a:msg
  aug Pecho
    au CursorHold * if s:Pecho!=''|echo s:Pecho
          \|let s:Pecho=''|if s:hold_ut > &ut |let &ut=s:hold_ut|en|en
          \|aug Pecho|exe 'au!'|aug END|aug! Pecho
  aug END
endf

In this form, I think it's safe for use in plugins.


I have noticed this too and used a similar approach to create a list of messages that should be put out at the end of command execution, but didn't think of using CursorHold. An alternative simpler solution is to put an extra newline at the end of the message such that the second empty line gets overwritten instead of the actual message, however this causes a Press Enter prompt (if the 'cmdheight' is 1).


" This update eliminates all "if" statements and introduces
" a locked variable to prevent collisions. Should a call to
" Pecho occur before the CursorHold is triggered, that call
" will wait for the triggering to unlock.
let PechoLock = 0
fu! s:Pecho(msg)
  wh islocked("g:PechoLock")|sl|endw
  lockv g:PechoLock|let s:hold_ut=&ut|let &ut=1
  let s:Pecho=a:msg
  aug Pecho
    au CursorHold * ec s:Pecho
          \|let &ut=s:hold_ut|unlo g:PechoLock
          \|aug Pecho|exe 'au!'|aug END|aug! Pecho
  aug END
endf

Around Wikia's network

Random Wiki