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 '20 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 '20 at 22:01
  • 1
    I have added aditional information in the question
    – Kes
    Apr 30 '20 at 22:10
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 '20 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 '20 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 '20 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.

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .