2

I created a file named test.vim containing code below.

vim9script var a = 1 echo a export var b = 2 echo b 

I copy that file to these place:

  • ~/Documents/test.vim
  • ~/.vim/test.vim
  • ~/.vim/pack/test.vim
  • ~/.vim/pack/testing/start/testing-vim/test.vim
  • ~/.vim/pack/testing/start/testing-vim/autoload/test.vim

I cd to each of above and open the test.vim file and source it, each gives the expected output:

1 2 

But when I source it the second time, the file in the last directory gives this error:

line 5: E1041: Redefining script item: "b" 

Is this the intended behaviour? I find this trouble when writing and testing a plugin in that directory.

If this is actually the intended behaviour, is there a way to disable this?

I use version 9.1.1498.

5
  • 1
    What is the point of this test? Of those 5 paths, only the last one makes sense and it is not supposed to be sourced explicitly or several times anyway. Commented Jul 8 at 15:20
  • @romainl Consider I have calculator.vim and complex-number.vim. In complex-number.vim I did export class Complex and this class is imported in calculator.vim. When I am not in that last path, I can easily test the Complex class directly inside complex-number.vim when adding a feature (using echo, for example), since I can source it multiple times. (Or is this actually the bug?) But when it is already in the vim pack path, since I cannot source the file multiple times, to test it I have to use the whole plugin by opening and closing another vim session. Commented Jul 8 at 15:51
  • Let's see your real code intead of a contrived example. Commented Jul 8 at 16:59
  • I have made some tests and I indeed notice that the exportation of a function in autoload do not prevent that the corresponding file is "reloaded" (i.e. so %) to recompile it and get the new version. But the exportation of a variable in autoload do prevent that the corresponding file is "reloaded" (i.e. so %) to recompile it and get the new version of the variable. Commented Jul 8 at 17:38
  • @romainl Clone this repo somewhere outside vim pack path. Navigate to autoload dir and open AstPrinter.vim. Near bottom of the file I have a commented test that I use when I implement that. Uncomment that. Source this file once. Modify the test. Source again. It works. Now clone again to vim pack path. And do the same. It doesn't work. By using the accepted answer with my binding (see also my answer) it now works. This might be not the common workflow. But I think it is really useful. Commented Jul 9 at 6:31

2 Answers 2

1

In order to reload your file in autoload a solution is to unlet the exported variables:

:unlet testing-vim#b 

Or (if you rename testing-vim into testing):

:unlet testing#b 

Remark: It seems to me that Vim plugin developed in vim9script should not have - in their name. It create problem in the exported object name (not allowed to include a -).

3
  • 1
    Great, thanks. I also found that when a file outside vim pack path is sourced, no exported item is listed when I enter :let g:. But it is listed when I do that inside vim pack path. So that's why I need to unlet it. I will also add my own answer to automate this. Commented Jul 9 at 5:22
  • Thanks for the feedback :-) Commented Jul 9 at 5:24
  • Feel free to edit mine if you like. Commented Jul 9 at 5:25
2

Using the answer from @Vivian De Smedt above I created a binding to automate/generalize the unlet. This is sufficient for my use case.

nnoremap <leader>u :call UnletExported()<CR> " NOTE: Only use for exported names from ~/.vim/pack/*/start/*/autoload/ path. function! UnletExported() let filename = expand("%:t:r") let exportLines = [] g/^export/call add(exportLines, getline(".")) if exportLines == [] echo "no export lines" return endif let exportedVars = [] for line in exportLines let words = split(line, '\ \+') if words[1] != "abstract" if words[1] != "def" call add(exportedVars, $"g:{filename}#{words[2]}") endif else " Handle abstract class exports. call add(exportedVars, $"g:{filename}#{words[3]}") endif endfor if exportedVars == [] " This means all export are for functions. echo "no exported variables" else for var in exportedVars if exists(var) echo $":unlet {var}" exe $":unlet {var}" endif endfor endif endfunction 

Edit: handle abstract class export.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.