3

I'm trying to use :! to run my test suite.

The file I'm working on is: /foo/bar/baz.py

My tests are in: /foo/test

I tried running :!../python -m unittest test but I get the following

error:/bin/bash: ../python: No such file or directory

shell returned 127

How do I tell VIm to execute a command in the parent directory of my currently loaded buffer? Or more generally, can I tell VIm to execute a command in the root folder of my project regardless of what file I am looking at?

2 Answers 2

7

To execute a command in the parent directory of Vim's current working directory, just precede the command with cd ..;, like this example using ls:

:!cd ..; ls

To execute a command in the parent directory of the current buffer, precede the command with cd %:h/.., e.g.,

:!cd %:h/..; ls

See

:help filename-modifiers

How to execute a command in the root folder of your project depends on its relationship to Vim's current working directory or on whether there is some environment variable naming it. In the latter case, say your project root directory is in $PROJROOT, then the Vim command would be:

:!cd $PROJROOT; ls

Note that since Vim executes :! command in a sub-shell, the cd affects only that sub-shell and doesn't affect Vim's current working directory.

If you start Vim in the root folder of your project and don't have 'autochdir' set, Vim's current working directory will remain the root folder regardless of the file you are looking at and executing your command in that directory should just work without the need for any leading :!cd ....

2

The problem is the command being invalid. Your shell /bin/bash searches for an executable, in this case python (try which python to see where it is located), which in turn requires specific arguments.

If test is the path, assuming you are one directory down, the correct command would be:

:!python -m unittest ../test

As garyjohn explained here, you can change the (sub) shell directory (the one created by bash) with :!cd. Yet another alternative is to set Vim's current directory (:pwd) with :cd.


You will also find tons of plugins fulfilling this use case (run a program in the background, linter or compiler for example), vim-test comes up as the first Google result.

There is Syntastic, a fully-featured syntax checker but lacks asynchronous capability, blocking the terminal while waiting for the program to run. That may change since Vim 8 supports async jobs.

If you run Neovim, Neomake is the perfect match.

Though I switched to the Asynchronous Lint Engine and I am still using it today.

If you use a lot of other filetypes as well, combine one of these linters with the language pack polyglot and you are good to go!

Your Answer

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

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