invalid back reference on MSYS2
Konfekt opened this issue · 5 comments
Hello,
the line
vim-startify/autoload/startify.vim
Line 662 in 81e36c3
leads to an error message
line 4:
/c/\12
line 5:
E65: Illegal back reference
as shown by
let fname = '/c/\12'
let fname = fnamemodify(fname, ":p")
let fname = glob(fname)
if v:oldfiles contains file paths with back and forward slashes (as happens when using Vim in MSYS2 and Windows).
Maybe the slashes should be all converted to \
if exists('+shellslash') && !&shellslash
and to /
otherwise?
Just experienced an issue with this same line in s:filter_oldfiles_unsafe(...)
. Turned on s:filter_oldfiles_unsafe = 1
and now i see: E944: Reverse range in character class
when i start gvim. The same issue i think, special characters in fname cause errors.
Example of my issue with this line caused by [ ] in fname:
let fname = 'D:\test\.vimrc [automatic-backup].vimrc'
let absolute_path = glob(fnamemodify(fname, ":p"))
E944: Reverse range in character class
Doing this before fnamemodify(...) will fix my issue but more robust special-character escaping is needed for all cases:
let fname = substitute(fname, '\[', '\\\[', 'g')
let fname = substitute(fname, '\]', '\\\]', 'g')
EDIT: No the above fix only stops the error from occurring.
This is correct (for windows only): let fname = substitute(fname, '\[', '\[[]', 'g')
By :help wildcards
,
? matches one character
* matches anything, including nothing
** matches anything, including nothing, recurses into directories
[abc] match 'a', 'b' or 'c'
therefore something like
if exists('+shellslash') && !&shellslash
" win32
let fname = substitute(fname, '\([[\]*?]\)', '\\[\1]', 'g')
else
let fname = substitute(fname, '\([[\]*?\\]\)', '\\\1', 'g')
endif
should work
The win32 section needs some changes. Its causing files like D:\[test].txt
to be filtered out of the recent file list.
let fname = 'D:\test\.vimrc [automatic-backup].vimrc'
" win32
let fname = substitute(fname, '\([[\]*?]\)', '\\[\1]', 'g')
echo fname
" D:\test\.vimrc \[[]automatic-backup\[]].vimrc
I think it should be: D:\test\.vimrc [[]automatic-backup].vimrc
according to :help wildcards
The following fixes the win32 side:
if exists('+shellslash') && !&shellslash
" win32
let fname = substitute(fname, '\[', '\[[]', 'g')
" Don't think this line is needed. Windows paths can't contain '*' and '?' (well there are exceptions to this, like DOS device paths can contain '?', https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats but i don't think they need to be escaped.
let fname = substitute(fname, '\([*?]\)', '\\\1', 'g')
else
let fname = substitute(fname, '\([[\]*?\\]\)', '\\\1', 'g')
endif
Updated accordingly, though in let fname = substitute(fname, '\[', '\[[]', 'g')
I wonder why \[[]
instead of [[]
Good question. I copied the let fname = substitute(fname, '\[', '\[[]', 'g')
line from the s:show_sessions()
function. From what i can tell let fname = substitute(fname, '\[', '[[]', 'g')
works identically, i.e. \[[]
and [[]
both insert [[]
. Not sure why '[' is escaped? Help indicates some characters have special meaning in the {sub} argument (but nothing related to '[' that i could see).
:h substitute()
:h sub-replace-special