0

So, I had this keymapping for helping me to edit files:

nnoremap <Leader>e :e **/

But this doesn't work with hidden directories. So, I naively added:

nnoremap <Leader>d :e .**/

But this only worked if the root directory was hidden. All the other hidden directory in the directory tree would be ignored.

So, I learnt from :h starstar that ** is not used as *. So, I can't do something like [.]?**. And then I found out :h backtick-expansion.

I'm doing following which gives me all the files with .vim extension according to the output of the find unix command, and I can tab through them.

:e `find . -name '*.vim' -print`

How wonderful! But from :h backtick-expansion, I see:

        :e `find . -name ver\\*.c -print`

The backslashes before the star are required to prevent "ver*.c" to be
expanded by the shell before executing the find program.

So, my questions are

  1. Why using single quotes after -name doesn't require * to be escaped with backslashes?
  2. When would using single-quotes require escaping with backslashes?
  3. Is there any obscure part in backtick-expansion that I have totally missed?
  4. How would I beautify this stupid mapping?
    nnoremap <Leader>o :e `find . -name '' -print`<left><left><left><left><left><left><left><left><left>
    

1 Answer 1

3

Let me try to answer your questions here. We are going to touch shell command language here. It basically comes down to quote the arguments correctly, so that the shell does not expand them unintentionally. So to your questions:

1) Why using single quotes after -name doesn't require * to be escaped with backslashes?

:e `find . -name '*.vim' -print`

This passes the command find . -name '*.vim' -print to your shell. The single quotes prevent the shell from expanding the * to all vim files that are laying around in the current directory. (Sidenote: If your current directory does not contain any .vim files, the * is usually passed through to the command [well, depending on your shell and certain shell options]).

The alternative is of course to backslash escape the * to prevent the shell from expanding.

2) When would using single-quotes require escaping with backslashes?

Off the top of my head, I don't currently think there is any necessity to need escaping within single quotes, except for preventing backslash escapes from being interpreted. There are two exceptions, however:

  • The command to be executed requires escaping for certain parts of the pattern. One example is if you want to print foobar\n1 in the shell, you can use printf 'foobar\n1' will actually print:

     foobar
     1
    

    So instead, you need to use printf 'foobar\\n1.

  • When run from within Vim, you need to escape the #, % (and possibly others which I currently do not remember). So you need to escape those so that Vim won't try to replace those parts with the name of a file before passing the command to your shell.

3) Is there any obscure part in backtick-expansion that I have totally missed?

Yeah, I think this is only supported to work correctly on Unix like operating systems. I don't think this is all portable (and I believe Bram has mentioned in the past that he does not intend to enhance this further (when I mentioned I'd like to have a certain bug fixed)).

4) How would I beautify this stupid mapping?

nnoremap <Leader>o :e `find . -name '' -print`<left><left><left><left><left><left><left><left><left>

I am leaving this for others to answer. I don't really care how beautiful a mapping looks like. :)

It should also be possible to use repeat() to return several times the same argument, but my basic attempt failed. Perhaps it is still to early for me to make this work :)

(a bit later) Ah, this seems to work:

 nnoremap <expr> <Leader>o ":e `find . -name '' -print`".repeat('<left>', 9)
1
  • Thanks. I actually use linux so that this kind of stuff is supported. So, I don't care about portability. And I also found out the mapping ASA I remembered about :h :map-<expr>
    – 3N4N
    Mar 21, 2019 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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