1

I am using nvim v0.4.3. This is the latest version available in repository. I have an Arch build with the most up to date packages and kernel 5.6.4-arch1-1.

I have the below function in my ~/.vimrc:

" function
function! ReSource()    
    let l:winview = winsaveview()    
    :source ~/.vimrc<cr>    
    call winrestview(l:winview)    
endfunction    

" function call    
nnoremap <leader>z :call ReSource()<cr>    

It does not work.

When I call it, NeoVim complains about my re-sourcing the .vimrc file, but the file permissions for ~/.vimrc are OK.

The function should save the exact cursor position and screen buffer when I press \z and then return to this exact layout after (re)sourcing my vimrc. That is why I use the function.

The error I get when I hit \z to call the function is as follows:

Error detected while processing function ReSource:                                                                          
line    3:
E484: Cannot open file ~/.vimrc<cr>
Press ENTER or type command to continue

And yet when I use the below simple single line instead, without the function, it sources and re loads .vimrc perfectly.

nnoremap <leader>z :source ~/.vimrc<cr>

What's wrong with the function?

Additional Information

Within the function, if

  1. I remove the : and <cr> from :source ~/.vimrc<cr>,
  2. save my ~/.vimrc,
  3. close it,
  4. reopen it,
  5. and press \z,

I get this error:

Error detected while processing ~/.vimrc:                                                               
line  399:
E127: Cannot redefine function ReSource: It is in use
Press ENTER or type command to continue

Line 399 is the endfunction line

3
  • 1
    The problem is the <cr> at the end. Vim is taking that literally, looking for a file named .vimrc<cr>. Remove the <cr> and it will work. (Also, you can remove the : at the start, it's not needed in a function.)
    – filbranden
    Apr 30, 2020 at 21:59
  • There was a similar issue in recent question BufLeave: Auto save split file not working, I'd consider marking this as a duplicate.
    – filbranden
    Apr 30, 2020 at 22:01
  • 1
    I have added aditional information in the question
    – Kes
    Apr 30, 2020 at 22:10

2 Answers 2

2

As @LucHermitte pointed out, the problem causing the E127 error is that you're trying to redefine function ReSource() while that function is running.

Note that you don't need to use a function to save and restore the cursor while sourcing your vimrc, only thing is that you'll end up using a global variable, but you can clean up after yourself in the same mapping.

nnoremap <leader>z :let vimrc_winview = winsaveview()<Bar>source ~/.vimrc<Bar>call winrestview(vimrc_winview)<Bar>unlet vimrc_winview<CR>

That's a long command-line... But it should work and wouldn't cause the issue with redefining a function. (Redefining a mapping while it's running should be just fine.)

3
  • 2
    I have :command -bar Reload source $MYVIMRC <bar> nohlsearch and don't have any problems with save/restore-ing cursor position (AFAIK—I don't tend to notice that when I'm editing unless it gets in the way)
    – D. Ben Knoble
    May 1, 2020 at 1:27
  • 3
    I've missed the cursor restoration. I'd then also say that "you shouldn't move the cursor in the .vimrc nor play with windows/buffers". May 1, 2020 at 1:28
  • 2
    Great point @LucHermitte ! Kes, take a closer look at what might be changing the cursor position and/or view in your vimrc and address that instead of using a mapping that saves/restores it when reloading...
    – filbranden
    May 1, 2020 at 2:43
3

First, <cr> in the mapping validates the command -- as we do interactively in the command/ex mode. In a script/function, we shall not add <cr> to commands -- each line validates a command. TL;DR: It should be source ~/.vimrc in the .vimrc

Then, as the error message says: we cannot redefine a function while it's being executed. IOW, a function defined within a script cannot source that script. The function definition shall be protected.

if ! get(s:, 'reloading', 0)
    " Useful when our vimrc isn't $VIMRC (it's my case to ease portability between windows and *nix)
    let s:script = expand('<sfile>:p')
    function! s:Reload() abort
        let s:reloading = 1
        try
            exe 'source '.s:script
        finally
            unlet s:reloading
        endtry
    endfunction
endif
nnoremap <leader>z :<c-u>call <sid>Reload()<cr>

Is it worth the trouble? I don't think so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.