Friday, December 16, 2011

Re: Replace

Am 11.12.2011 21:23, schrieb Marcin Szamotulski:
> Dear vim_use,
>
> I wrote a function which replaces the vim "r" normal command. But then
> vim the normal command "." breaks. The simplest way to reproduce it is
> to use:
>
> fun! Replace()
> let char=nr2char(getchar())
> exe "normal! r".char
> endfun
> nmap r :call Replace()<CR>
>
> then rx will replace a letter the current cursor position to x. The .
> register will shows x. But if I use . the text from the current cursor
> position till the place where I used rx is copied into the buffer. Any
> ideas how to get . work?
>
> Thanks,
> Marcin

There are many ideas ...

Use <expr> mapping, let result of evaluation be "r{char}".

:nn <expr> r "r". nr2char(getchar())
or
:nn <expr> r Replace(getchar())

Pro:
Builtin repetition with "." works. getchar() directly called in the
{rhs} will make "." not ask for a character again.

Con: (older Vims (!))
Bug with expression mappings: getchar() will not take a character from
the typeahead, instead it always asks the user. For example, if there
are other mappings starting with "r" (:nn r<BS> <Nop>), then Vim can't
execute "r" until another character is typed, which goes into the
typeahead buffer. The character typed after that is then read with
getchar(). E.g. typing "rxa" results in "rax".


Create <SID> mapping to execute the result:

nn <script> r :call Replace()<CR><SID>Cmd

fun! Replace()
call inputsave()
let char = nr2char(getchar())
call inputrestore()
exec "nn <SID>Cmd r". char
endfun

Con: always asks the user, never take characters from typeahead (doesn't
work in mappings)
Pro: "." works


func! Replace(sid)
let char = nr2char(getchar())
call feedkeys(a:sid."Cmd")
endfunc

nn r :call Replace("<SID>")<CR>

Con: doesn't work in mappings, feedkeys() always places commands at the
end of the typeahead.


Solution so far (with bells and whistles (<c-u>, <silent>, count, ...)):

nn <silent> r :<C-U>call Replace("<SID>")<CR>
nn <silent> <SID>InputRestore :call inputrestore()<CR>

func! Replace(sid)
let char = nr2char(getchar())
exec printf("nn <SID>Cmd %sr%s", (v:count>=1 ? v:count : ""), char)
let sid = eval('"\'.a:sid.'"')
call inputsave()
call feedkeys(sid."Cmd". sid."InputRestore")
endfunc


Or maybe repeat.vim is another option
http://vim.sf.net/scripts/script.php?script_id=2136

--
Andy

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments:

Post a Comment