3

Tabnew works when the filename is given directly. I want to open a file using Its alias since the file is far away from the current file path and difficult to remember or type. I use alias command for files in .cshrc file.

Example:

# .cshrc
Alias abs vim /project/userid/trees/soft/abs.pl

In shell command line

/home/userid> abs
# -> Vim opens the file.

Now, I tried

:tabnew !abs

It opens a file named !abs instead of original file. Is there a way to combine commands using pipe or something like that, so that this filename is returned and tabnew opens it?

  • I removed vim from the alias part and tried. Still it didn't work – SibiCoder Apr 20 '16 at 7:53
  • It works with a pipeline in between. :tabnew | !abs opens my file. Do I need to delete this question? @Nobe4 – SibiCoder Apr 20 '16 at 8:13
  • 1
    I think you should answer your own question for further reference. – nobe4 Apr 20 '16 at 8:15
  • 4
    @SibiCoder depending on your needs you could also be interested in the use of marks. Instead of creating an alias in your shell's rc file you could open your file with Vim once and mark it with mA (you can replace A by any capital letter). Then at any time you can use 'A to reopen this file (even if you closed vim). You can use :marks to see all of your bookmarks. See :h bookmark for more information. – statox Apr 20 '16 at 10:02
  • 3
    I'm reasonably certain :tabnew | !abs starts a new Vim instance after opening a new tab, instead of opening a tab with that file loaded. (Compare: what will happen if you run just :!abs?) – muru Apr 20 '16 at 10:56
6

From :help backtick-expansion:

                    *backtick-expansion* *`-expansion*
On Unix and a few other systems you can also use backticks for the file name
argument, for example: >
    :next `find . -name ver\\*.c -print`
    :view `ls -t *.patch  \| head -n1`
The backslashes before the star are required to prevent the shell from
expanding "ver*.c" prior to execution of the find program.  The backslash
before the shell pipe symbol "|" prevents Vim from parsing it as command
termination.

So, if you want to edit a filename given by the output of a shell command, you could write:

:tabe `your shell command`

Vim should open the file given by the output of your shell command in a new tab.
Note that if your shell command contains a pipe, it must be escaped to prevent Vim from parsing it as a command termination.


Besides, I'm not sure, but I think that if the output contains special characters, it won't work as expected and you will have the error E79: Cannot expand wildcards.

Again, not sure, but I suspect it's because after getting the output of the shell command, if Vim sees some special characters, it tries to perform an expansion on them but sometimes the pattern can be illegal (see :h e79 for more information).

In this case, :help `= might help you:

                            *`=*
You can have the backticks expanded as a Vim expression, instead of as an
external command, by putting an equal sign right after the first backtick,
e.g.: >
    :e `=tempname()`
The expression can contain just about anything, thus this can also be used to
avoid the special meaning of '"', '|', '%' and '#'.

This syntax seems more reliable, maybe because Vim doesn't perform any expansion after evaluating the expression which follows the = sign.

Thus, you could also write:

:tabe `=system('your shell command')`

Note that with this 2nd syntax, you don't need to escape a pipe character.


However, as @muru explained, I don't think that what you are trying to achieve is possible, because no matter the syntax you use, your shell alias abs doesn't echo the path to a file, it simply launches a new Vim session.

But maybe you could export an environment variable in a file sourced by your shell like ~/.bashrc:

export ABS=/project/userid/trees/soft/abs.pl

And then type in Vim:

:tabe $ABS

If the session was launched from the shell, Vim should know the environment variable and expand automatically $ABS.

Another working case is given in your last comment: you want to open the file given by the shell command ls -1 | tail -1 in a new tab. You could achieve this with:

:tabe `ls -1 \| tail -1`

or

:tabe `=system('ls -1 | tail -1')`
2

Using a pipeline solves the problem.

:tabnew | !abs

Opens the file through alias. Similarly, you can use any system command and open the same way.

:tabnew | !perl a.pl
  • @nobe4 but it doesn't work when I use multiple pipelines, example: tabnew | !ls -1 | tail -1 should open the first file in the directory. But it doesn't work the expected way – SibiCoder Apr 20 '16 at 8:28

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.