David Fishburn schrieb:
> Vim 7.2.1-79 WinXP SP3
>
> The YankRing uses expression maps and omaps.
>
> In order to handle the f, F, t, T (and some others) it has to prompt
> the user for the following key:
> df_  (delete forward to the _).
>
> When hitting . (to repeat) an action, the user does not want to be
> prompted again for the same action.  So in this case, the YR
> temporarily removes the mapping, executes the command and re-adds it.

I don't think this is needed, see my older post:
http://groups.google.com/group/vim_use/msg/6cb2115dbbcfcd3b
The following code makes use of it.

Ok, the backdraw is: it will not work from a mapping or from @a (your
new problem below), because getchar() -- when called from an expr-map
(!) -- for some reason does not take the next char from available type
ahead (as it should), but always asks the user for fresh input.


omap w w<SID>copyreg

" if the following is repeated with "." (e.g. "df_.") the expression
" will not be evaluated again:
ono <expr><script> f "f". <sid>Getchar(). "<SID>copyreg"
ono <expr><script> F "F". <sid>Getchar(). "<SID>copyreg"

" (should work as well:)
" omap <expr> f "f". <sid>Getchar(). "<SID>copyreg"

map . .<SID>copyreg

nnoremap <silent> <SID>copyreg :call <sid>Record()<cr>
inoremap <silent> <SID>copyreg <C-R>=<sid>Record()<cr>

if !exists("g:yankring")
    let g:yankring = []
    let g:yr_attr = []
endif

func! <sid>Getchar()
    let c = getchar()
    if c != 0
        let c = nr2char(c)
    endif
    return c
endfunc

" add to the yankring, prevent duplicates, :echo what has been added
func! <sid>Record()
    if v:register =~ '\a'
        " don't record what the user saves explicitly in a named
        " register
        return
    endif
    let reg = getreg(v:register)
    let attr = {
        \ "regtype": getregtype(v:register),
        \ "size": strlen(reg) }
    let index = index(g:yankring, reg)
    if index != 0
        if index > 0
            call remove(g:yankring, index)
            call remove(g:yr_attr, index)
        endif
        call insert(g:yankring, reg)
        call insert(g:yr_attr, attr)

        let yrlen = len(g:yankring)
        if yrlen > 50
            call remove(g:yankring, 50, yrlen-1)
            call remove(g:yr_attr,  50, yrlen-1)
        endif
    endif
    echo "reg [". v:register. "]:". reg
    return ""
endfunc


> Another case where this is necessary has been found and it deals with
> recording macros.
> qa
> df_
> q
>
> @a
> When the df is entered, the YR once again prompts for the character (_).
> I have handled this by creating a normal map for @, and prompt the
> user for the register to run the macro from.
> This is working well so far, it can also handle counts 4...@a.

How do you actually try to avoid the prompts when executing the macro?

> I have run into a snag where I hope someone can help.
>
> If the user does this:
> 1,3normal! @a
>
> Everything works due to the use of the ! which prevents maps from firing.
> But if the user does:
> 1,3normal @a
>
> Things don't work since my mapping does not get the user input for
> which register to run the macro from.

Looks like @ is "expr-mapped", ignoring the type ahead "a".

> What I was hoping was there was some way from within an expression
> function to see the full normal command.  Kind of like v:operator
> which allows me to see what came before the omap, but not after.
>
> So in my expression function, I could check if the user already
> entered the "a" and use it.
>
> Any suggestions?

expr-maps and getchar():
I don't know if this is a bug in Vim, but if getchar() is called to
build the {rhs} of an expr-mapping to be executed, it will not fetch
characters from the following type ahead, but always prompts the user
for fresh input (yap, I'm repeating myself here).  At least this is what
I've observed so far.

-- 
Andy


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply via email to