Search code examples
vimnetrw

vim netrw-qb conflicts with q recording


Under netrw, pressing qb(query bookmark) will list bookmarks etc. But this key is preempted by q recording. It becomes recording to register b.

What's your suggestion to deal with this?


Solution

  • TL;DR

    Just place the following to your .vimrc file.

    autocmd FileType netrw noremap <buffer>q <Nop>
    

    I have not found any command in the help netrw but you can always type tabe . | :nnoremap qb and get as the output:

    n  qb          *@:<C-U>call <SNR>75_NetrwBookHistHandler(2,b:netrw_curdir)<CR>
    

    You will be wrong if you just nnoremap this to a qb since the script id (75) may be changed in the future. So the following is wrong, do not do this:

    autocmd FileType netrw noremap <buffer><silent>qb :call <SNR>75_NetrwBookHistHandler(2,b:netrw_curdir)<CR>
    

    As netrw help file says there is an option g:Netrw_UserMaps which allow us to bind user functions help netrw-usermaps.

    Solution #1

    function! NetrwBookHistHandler(isLocal)                                                                                                                                       
        return "call <SID>NetrwBookHistHandler(2, b:netrw_curdir)"
    endfunction
    
    let g:Netrw_UserMaps = [["qb", "NetrwBookHistHandler"]]
    

    Function returned string, if not empty, will be executed in the netrw script context which makes possible to access actual <SID>.

    Update

    Solution #2

    If you type :call netrw#<C-D> you will see there is a function called netrw#Call. So the solution becomes a little bit easier:

    autocmd FileType netrw noremap <buffer><silent>qb :call netrw#Call("NetrwBookHistHandler", 2, b:netrw_curdir)
    

    Update 2

    Unfortunately, there is a bug in netrw plugin code.

    " /usr/share/nvim/runtime/autoload/netrw.vim
    
    fun! netrw#Call(funcname,...)                                                                                                                                                 
    "  call Dfunc("netrw#Call(funcname<".a:funcname.">,".string(a:000).")")
      if a:0 > 0
       exe "call s:".a:funcname."(".string(a:000).")"
      else
       exe "call s:".a:funcname."()"
      endif
    "  call Dret("netrw#Call")
    endfun
    

    When we call netrw#Call("NetrwBookHistHandler", 2, b:netrw_curdir) the function itself call NetrwBookHistHandler([2, b:netrw_curdir]) while NetrwBookHistHandler expects 2 parameters. Use the second and the easiest solution.

    Solution #2

    autocmd FileType netrw noremap <buffer>q <Nop>