5

Could this be done?

For example, I'm imagining that I would type vim . then navigate to a different directory within netrw, exit netrw, and find that bash has done a cd to that same directory.

4 Answers 4

4

No it isn't possible. Vim will be the child of your bash process. A child can't change the current directory of its parent (except by doing tricky and very discouraged things: https://stackoverflow.com/questions/2375003/how-do-i-set-the-working-directory-of-the-parent-process). You may also want to read: https://unix.stackexchange.com/questions/141313/chdirdirectory-doesnt-change-directory-after-exiting-to-shell

Maybe you could achieve writing a tiny vimscript launched at startup and printing the current directory (of the child process being vim) when exiting, and write some bash alias for something like cd `vim -c ...`. But why on earth would you do such a tricky thing?

2
  • The university filesystem hierarchy is big and weird, but I like the command line, so I'd rather not use a file manager. I have no regular pattern of visits, so aliases for each directory become numerous, often obsolete, and a bit forgettable. I open a lot of text files with netrw so it just seemed like a solution that was already part of what I do. I'll try your "maybe" solution. Thanks!
    – user251764
    Nov 16, 2015 at 10:07
  • @user251764 I understand; however I don't like much the idea of using a text editor for such a thing. If a tool like midnight commander doesn't suit your expectations, maybe you could have a look at tools like commacd or z or j or j2 or autojump or fasd (see: inconsolation.wordpress.com/2014/11/17/… ) I don't use such tools myself, but in case it may help... Nov 16, 2015 at 10:14
2

You could, but it would take a little scripting: adding to netrw and writing a bash function wrapper for vim. Ranger, a file manager with vi key bindings, and wcd, Wherever Change Directory, do this. Take a look at their documentation for examples. The idea is that you add a shell function, named ranger or wcd, respectively, to your ~/.bashrc, which calls the actual program. The user uses the features of the program to select the new directory which the program then writes to a temporary file, then exits. The function reads the new directory name from that temporary file and cd's to it. In your case, you would have to add a command to Vim to write the current directory (selected by netrw) to a temporary file, then exit Vim. Your vim wrapper function would then read that file and cd to the directory it names.

4
  • 1
    Would you seriously advise someone to do this? Nov 14, 2015 at 20:12
  • 2
    @Baruchel: The question was, "Could this be done?" The answer is "yes". Whether someone finds it useful is up to them. It's not a great idea, but it's not harmful, either.
    – garyjohn
    Nov 14, 2015 at 20:41
  • Thank you garyjohn, I will try your two filemanagers soon. I may well find them more useful than netrw
    – user251764
    Nov 16, 2015 at 10:15
  • @ThomasBaruchel I wonder why not, if netrw is for file and folder browsing then change directory must be a normal feature
    – Ahmad
    Jan 5, 2022 at 5:53
0

I wrote up a solution for this. It has two parts, a shell function that launches Vim and changes to its directory when Vim exits, and a vimrc edit that writes the current directory to a temp file when Vim quits.

Add the following to your vimrc, to write the current directory to a temp file when you exit Vim:

" Write directory to temp file
let s:temporary_directory = "/tmp/vimtmpfiles/"
let s:chdirectory_directory = s:temporary_directory . "chdir"
let s:chdirectory_file = s:chdirectory_directory . "/chdir"
if !isdirectory(s:chdirectory_directory)
  call mkdir(s:chdirectory_directory, 'p')
endif
function! s:isdir(dir)
  return !empty(a:dir) && (isdirectory(a:dir) ||
        \ (!empty($SYSTEMDRIVE) && isdirectory('/'.tolower($SYSTEMDRIVE[0]).a:dir)))
endfunction
augroup write_chdir
  autocmd!
  autocmd VimLeavePre *
        \ if <SID>isdir(expand('%'))
        \ | call writefile([expand('%:p')], s:chdirectory_file)
        \ | endif
augroup END

Add the following to your bashrc and launch Vim with it:

vim_cd() {
  local tempfile='/tmp/vim.robenkleene/chdir/chdir'
  $VIM_COMMAND .
  test -f "$tempfile" &&
    if [ "$(cat -- "$tempfile")" != "$(echo -n `pwd`)" ]; then
      cd -- "$(cat "$tempfile")"
    fi
}

This was assembled by combining this Stackoverflow answer https://vi.stackexchange.com/a/10474 and this function for Ranger https://github.com/ranger/ranger/blob/master/examples/bash_automatic_cd.sh

0

You can use netrw to navigate to a directory, then c to set browsing directory to the current directory. You can then :shell to do some work in that directory, then exit back to netrw.

I find this handy when I work on git repos located in different places in my filesystem (I have a script that shows my repos, their status, and conflicted files which I then pump into vim and use netrw to get to them and do the work).

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.