Search code examples
pythonvimorg-mode

Baffled by solution to Vimscript recursion error


I want to use gf to open hyperlinked filenames in .org files (I use the vim plugin vim-orgmode):

enter image description here

I type gf and the file should open. To avoid having to move past the first two [[, I created the following script to do the job:

function! GFOrg()
python << EOF
import vim  
try:
    filename=vim.eval("@%")
    if filename.endswith(".org"):
        line = vim.current.line
        linkstart=line.find("[[")
        if linkstart != -1:
            row, start = vim.current.window.cursor
            vim.current.window.cursor = row, linkstart+2
    vim.command("normal gf")
except Exception as e:
    print("Error: {}".format(e))
EOF
endfunction

Now if I map it to override gf:

nnoremap gf :call GFOrg()<CR>

I get a recursion error:

enter image description here

But if I quit and reopen Vim (MacVim actually), and use gfgf as my mapping, I can just type gf (once) and it works fine:

nnoremap gfgf :call GFOrg()<CR>

Can anyone explain why I don't need to type gf twice to get mapped to the call, and why it stops the recursion error?


Solution

  • You are using :normal to call gf which will call you mapping again which is causing the recursion. You should be using :normal! to avoid re-mapping.

    That being said we can do better!

    • Should a buffer-local mapping
    • Only apply this mapping to buffer's the the 'filetype' of org

    Add the following to ~/.vim/after/ftplugin/org.vim:

    nnoremap <buffer> gf :call search('\[\[.', 'bce', line('.'))<cr>gf