I have a vim script, which uses Unix type path separator as:

"Prg: Expand snippets {{{!
let s:plugin_dir=filter(split(&rtp, ','), 'v:val =~ "/vimf90"')[0]
let s:templatedir=s:plugin_dir . '/templates/'
function! Prog(arg)
  execute 'r ' . s:templatedir . a:arg . '.txt'

I have never used Windows, so I was not aware that it may break in Windows. One of my users reported this issue:

The script works very well on Linux system, but when I try it on Windows, it does not work with the following error:

Error detected while processing
C:\User\Ki-Tae\vimfiles\plugged\vimf90\ftplugin\fortran_comp.vim: line
102: E684: list index out of range: 0 E15: Invalid expression:
filter(split(&rtp, ','), 'v:val =~ "/vimf90"')[0] line 103: E121:
Undefined variable: s:plugin_dir E15: Invalid expression: s:plugin_dir
. '/templates/'

Also, he was kind enough to send me back the solution as:

In Windows, forward slash should be backward slash, so the code should be

filter(split(&rtp, ','), 'v:val =~ "\vimf90"')[0]


s:plugin_dir . '\templates\'

Which he claims to work for him.

As far as I know, vim should alter the path separators inherently. But, clearly, this is not the case here.

The complete code in question is available here.

I will be grateful if someone kindly check this. I can't do that since I don't have any access to Windows.


Rather than explicitly specifying paths to the files you have in mind, try using built-in file path handling functions like expand() (potentially with <sfile>) or glob()/globpath().

For instance, if you're looking for the root directory of your own plugin, you might try

let s:plugin_dir = expand("<sfile>:h:h")

I'm not sure how glob will work, but you could try

let s:templatedir = glob(s:plugin_dir . '/templates')

maybe ask your user to give it a shot and tell you how it works?

| improve this answer | |
  • Remark, expand('<sfile>') needs to be executed at global script level, not within the scope of a function. – Luc Hermitte Jul 4 '17 at 14:51

I'd either make sure that neither / nor \ are in the &isk(momentarily), then match \<vimf90\>, or I'd match [/\\] ([/\\\\] actually because of filter()) -- I've plenty examples in path.vim module from my lh-vim-lib library plugin.

In mu-template, I didn't have your problem as I don't restrict my search for matching directories to {rtp}/somethinghardcoded/templates, but only to {rtp}/templates. This way, overriding is possible, i.e., with globpath(&rtp, 'templates') end-users will be able to override your templates in their $HOME/.vim/templates directory.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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