Vim Tips Wiki
Register
(New page: An easy way to overload a key (e.g. <tt>Esc</tt>) to make handling a keypress in different contexts more dynamic. The key is the following (trivial) function: <pre> function! RunHandlers(...)
 
(add comments section and map category)
Line 44: Line 44:
   
 
Adding more handlers should be easy enough. In this case, <tt>CloseScratch</tt> is tried first, and if that fails <tt>DefaultEsc</tt> is called. I've "wrapped" the trivial call to <tt>normal</tt> in a function so I can add an empty echo command to clear the Ex line (the bottom line) after pressing <tt>Esc</tt>.
 
Adding more handlers should be easy enough. In this case, <tt>CloseScratch</tt> is tried first, and if that fails <tt>DefaultEsc</tt> is called. I've "wrapped" the trivial call to <tt>normal</tt> in a function so I can add an empty echo command to clear the Ex line (the bottom line) after pressing <tt>Esc</tt>.
  +
  +
==Comments==
  +
Try using :silent or <silent> rather than an empty echo to make the bottom line clear.
  +
  +
*{{help|:silent}}
  +
*{{help|:map-silent}}
  +
  +
This is a pretty cool tip though! I like the idea of multiple things mapped to the same key.
  +
  +
[[Category:Map]]

Revision as of 22:31, 22 April 2008

An easy way to overload a key (e.g. Esc) to make handling a keypress in different contexts more dynamic. The key is the following (trivial) function:

function! RunHandlers( handler_list, default_action )
  let l:handled = 0
  for handler in a:handler_list
    if !l:handled
      execute "let l:handled = " handler."()"
    endif
  endfor
  if !l:handled
      execute a:default_action
  endif
endfunction

This function calls a list of handlers until one returns true, indicating the event was handled. If no handler returns true, a default function is executed.

Take for example, the CloseScratch function used in another tip of mine. Note that it's somewhat different: it now returns whether it actually did something (delete the current buffer), and no longer executes a default action (e.g. normal! <Esc>).

function! CloseScratch()
  let l:is_scratch = &buftype == "nofile" && &bufhidden == "hide" && !&swapfile
  if l:is_scratch
    bdelete
    echo ""
  endif
  return l:is_scratch
endfunction

Using RunHandlers I can now dynamically overload <Esc> to call this function (in normal mode), like so:

function! DefaultEsc()
  normal! "<Esc>"
  echo ""
endfunction

let g:esc_handler = []
call insert(g:esc_handler, "CloseScratch", len(g:esc_handler))
nmap <Esc> :call RunHandlers(g:esc_handler, "call DefaultEsc()")<CR>

Adding more handlers should be easy enough. In this case, CloseScratch is tried first, and if that fails DefaultEsc is called. I've "wrapped" the trivial call to normal in a function so I can add an empty echo command to clear the Ex line (the bottom line) after pressing Esc.

Comments

Try using :silent or <silent> rather than an empty echo to make the bottom line clear.

This is a pretty cool tip though! I like the idea of multiple things mapped to the same key.