On Fri, 20 Oct 2006 at 8:33am, Benji Fisher wrote:

> On Thu, Oct 19, 2006 at 11:26:53PM -0700, Hari Krishna Dara wrote:
> [snip]
> >
> > imap <buffer> <silent> <expr> <F12> Double("\<F12>")
> > function! Double(mymap)
> >   try
> >     let char = getchar()
> >   catch /^Vim:Interrupt$/
> >     let char = "\<Esc>"
> >   endtry
> >   "exec BPBreakIf(char == 32, 1)
> >   if char == '^\d\+$' || type(char) == 0
>
>      Don't you want =~ above instead of == ?

You are right, good catch. I copied this code from execmap.vim which
has been there for ages, and I don't even remember why I am checking for
this pattern, seems like the type() check is sufficient.

>
> >     let char = nr2char(char)
> >   endif " It is the ascii code.
> >   if char == "\<Esc>"
> >     return ''
> >   endif
> >   redraw
> >   return char.char."\<C-R>=Redraw()\<CR>".a:mymap
> > endfunction
> >
> > function! Redraw()
> >   redraw
> >   return ''
> > endfunction
> >
> > You can do almost eanything that you can do normally in an insert mode,
> > press <BS>, <C-U> etc. Hope someone finds this useful.
> >
> > I will also post this as a tip.
>
>      How does this approach affect the undo history.  That is, if I
> start in Normal mode and type "Afoo<Esc>" (without the quotes) can I
> undo the append with "u" and repeat it with "."?
>
> HTH                                   --Benji Fisher

The above code works only in insert mode and it plays naturally with
undo history (it uses <C-R>= to execute :redraw so it doesn't break
undo). If you extend the map to cover normal mode also, you can see it
clearly for the case you mentioned (I also removed an excess redraw that
I left out before)

imap <buffer> <silent> <expr> <F12> EatCapitals("\<F12>")
nmap <buffer> <silent> <expr> <F12> EatCapitals("\<F12>")
function! EatCapitals(mymap)
  try
    let char = getchar()
  catch /^Vim:Interrupt$/
    let char = "\<Esc>"
  endtry
  "exec BPBreakIf(char == 32, 1)
  if char == '^\d\+$' || type(char) == 0
    let char = nr2char(char)
  endif " It is the ascii code.
  if char == "\<Esc>"
    return char
  elseif char =~# '[A-Z]'
    " Eat it away, but continue to be in loop
    return "\<C-R>=''\<CR>".a:mymap
  endif
  return char."\<C-R>=Redraw()\<CR>".a:mymap
endfunction

function! Redraw()
  redraw
  return ''
endfunction

Press <F12> in normal mode and start typing your example. This will
ignore capitals, so what you will see is "foo" not "Afoo". Once you
press <Esc>, if you press ., you can see that "foo" gets inserted again.

I devised this technique for creating a read-only combobox for my forms
plugin. While on the combo field, this allows me to eat away all
characters except for those that let you select the item (<C-N> etc.)
and those that allows you to change focus (<Tab> etc.). I wish I can
extend this for all fields to completely control where the user is
typing and what he can do, but the problem is the cursor stays at the
bottom during this time so it will be hard to understand where you are
typing (and it won't feel natural either).

-- 
Hari

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

Reply via email to