3

Sometimes I gf to a file in a totally different directory and want to check out that new directory. Is there a way to quickly exit vim and cd into the directory containing the current buffer?

3
  • 1
    If I understand your request, no you can't quit Vim such that you end up in a different directory than you started because the shell is the parent process of the Vim process and a child process can't alter the environment of their parent. It's the same reason you can't do cd foo in a shell script and be in foo when the script exits.
    – B Layer
    Dec 23, 2020 at 12:26
  • 1
    Not directly related but a bit more info about this parent-child stuff (in the context of Vim's :cd command) here: vi.stackexchange.com/a/22949/11054
    – B Layer
    Dec 23, 2020 at 12:31
  • 1
    If you want to examine the directory of a newly opened file, you can use netrw like this: :Vexplore %:h or start a terminal :sp | cd %:h | term ++curwin Dec 23, 2020 at 13:33

3 Answers 3

5

I there is a mean but it use a plugin, to solve that simply.

First approach

If it's only to visualize the current directory, you can use the :term command:

:term ls %:p:h

(filtering result %=current buffer, p=path with file name, h= path only) It only display the content though.

You can also use the internal file manager with %:p:h as a parameter (with :e, or :tabnew or :sp or :vsp command):

:e %:p:h

That open the default file manager inside vim in this specific place. With that you can perform some actions (navigate, delete, copy, paste or modify some files)

With lf (file explorer with integrated terminal)

In my case, I use a plugin that integrate lf (my favorite terminal file explorer) as vim's internal file explorer. Luckily, lf as integrated terminal and can also lauch some shell (as bash, zsh, etc.)

Even outside of vim, it's a good and customizable tui.

Hope it will help you.

1

This generally can't be done, as the current directory is in a way part of the running environment of a running process and a process typically can't change the running environment of its parent process (in other words, Vim can't affect the shell that spawned it.)

(This is similar to why shell scripts generally can't set environment variables on the shell that spawned them, which is also something that comes up quite frequently.)

There are ways you can set up Vim and the shell to actually implement something like this, but you typically need to prepare the shell for it. In general you should replace the way you call Vim with a function that allows the shell to set up a communication channel so that Vim can tell it to change directories.

A little more specifically, you would create a shell function named vim (and possibly others called vi, view, vimdiff, etc. if you want this to work on all ways Vim can be invoked.) This function would set up a way for Vim to send the shell a directory name to cd into when done. For example, setting up a temporary file somewhere. Then the function would invoke the real Vim, passing it this communication channel (for example, through an environment variable with the path to the file where Vim could write.) Then you could set up Vim mappings, commands or autocmd's that would write a directory name to that file. Once you leave Vim, the shell function would inspect the file to see if Vim wrote to it and then run cd to move to the appropriate directory.

I find that tends to be pretty clunky, but it's definitely doable.

There are better alternatives though. You can start a new shell from inside Vim, with the :sh command. When you do so, the new shell will be created under Vim's current directory (see Vim's :cd command and also the 'autochdir' setting.) Recent versions of Vim can also run a shell inside a Vim window, with the :term command, and that shell will also be started under Vim's current directory. So rather than trying to affect the shell that launched Vim, you could consider starting a new one from inside Vim?

0

Yo can do it like this :cd %:p:h | cd .. than you can use telescope.nvim for example to select files.

5
  • 1
    Welcome to Vi and Vim! I'm having trouble following your answer: :cd %:p:h should already take Vim to the directory containing the current file (:cd .. not needed). And treesitter has nothing do with selecting files, AFAIK. Perhaps you meant to mention a file explorer or browser?
    – D. Ben Knoble
    Sep 6, 2022 at 14:29
  • Hi Ben, thank you. I just now saw I should have wrote telescope.nvim not treesiter I will edit my answer, sorry about that.
    – toni rmc
    Sep 6, 2022 at 18:14
  • As I understood question is about setting parent directory of the directory containing the current file as a cwd. For example your cwd in Vim is /pdf/books and you have file.c opened which is located in /my/projects/lib than :cd %:d:h will take Vim to /my/projects/lib yes, but if you do :cd %:d:h | cd .. than current working directory is /my/projects. telescope.nvim is very useful but it cannot go directory up it only searches in current one, so with the above command entered first you can for example use it to search everything in /my/projects instead of in /my/projects/lib.
    – toni rmc
    Sep 6, 2022 at 18:18
  • Q says directory containing the current file (buffer). Also, if you did want to go up a level, :cd %:p:h | Explore .. should work.
    – D. Ben Knoble
    Sep 7, 2022 at 2:33
  • Yes you are right Q was about directory containing the current buffer, I wasn't paying enough attention as parent of a parent is something I needed to set up for me just before I answered. :cd %:p:h | Explore .. will work also but I don't think it will set a directory one level up as a cwd though.
    – toni rmc
    Sep 7, 2022 at 4:16

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.