Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

invalid back reference on MSYS2 #538

Open
Konfekt opened this issue Sep 28, 2022 · 5 comments · May be fixed by #539
Open

invalid back reference on MSYS2 #538

Konfekt opened this issue Sep 28, 2022 · 5 comments · May be fixed by #539

Comments

@Konfekt
Copy link
Contributor

Konfekt commented Sep 28, 2022

Hello,

the line

let absolute_path = glob(fnamemodify(fname, ":p"))

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?

@FocusedWolf
Copy link

FocusedWolf commented Oct 10, 2022

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')

Konfekt added a commit to Konfekt/vim-startify that referenced this issue Oct 11, 2022
@Konfekt
Copy link
Contributor Author

Konfekt commented Oct 11, 2022

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

@FocusedWolf
Copy link

FocusedWolf commented Oct 11, 2022

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

Konfekt added a commit to Konfekt/vim-startify that referenced this issue Oct 12, 2022
@Konfekt
Copy link
Contributor Author

Konfekt commented Oct 12, 2022

Updated accordingly, though in let fname = substitute(fname, '\[', '\[[]', 'g') I wonder why \[[] instead of [[]

@FocusedWolf
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants