I have run into an escaping problem with the path argument to findfile({name}, {path}) / finddir({name}, {path}).

In my code path is a directory, obtained via fnamemodify(<file>, ':h').

Until recently I used fnameescape() to escape this path, before appending a semi-colon and passing it into findfile() / finddir().

However it turned out to break findfile() / finddir() with filenames containing #, because the # was escaped but evidently findfile() / finddir() don't unescape the #.

The docs for findfile() / finddir() don't talk about escaping. However they do say if the path argument is omitted, they use the value of the path option. The docs for the path option say spaces, commas, and backslashes have to be escaped with a backslash.

So I updated my code like this:

- fnameescape(dir)
+ escape(dir, ' ,\')

But this now breaks on Windows because it escapes backslashes (I think that's why).

What's the correct way to escape file paths for the findfile() / finddir() functions?

  • The space, comma and backslash have a special meaning to :set. The space can separate different options names, the comma can separate different values given to an option, and the backslash tell :set to disable the special meaning of the next character, which allows you to include a comma/space/backslash inside a value. You probably need to escape the spaces because they have a special meaning on the shell command-line. As for the backslashes, if they cause an issue, you should probably remove them from escape(). – user938271 Sep 28 '18 at 13:55
  • So, I'm not sure it would fix your issue, but I would try to use escape() like you did, but only to escape spaces. Btw, that's what tpope does in fugitive, eunuch, and dispatch. He uses something like findfile('some_file', escape(dir, ' ')). – user938271 Sep 28 '18 at 13:56
  • I forgot about the commas. They don't have a special meaning for findfile() (only for :set), so there's no reason to include them in escape(). – user938271 Sep 28 '18 at 14:02
  • @user938271 Thank you! I hadn't appreciated that the escaping in the path docs was for the benefit of :set. The links to fugitive, eunuch, and dispatch are helpful too. – Andy Stewart Sep 28 '18 at 14:11
  • @user938271 If you write your comments as an answer I'll be able to accept it :) – Andy Stewart Sep 28 '18 at 14:12

Your Answer

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

Browse other questions tagged or ask your own question.