I feel my current VIM setup is pretty sweet, but there is one thing that annoys me time and time again: how can I open a file or add a file to the same directory as the current file I am editing?

If I should open NerdTree it will just list the contents of $PWD and I need to manually browse down to where I want to go. I'd like to have a workflow a bit like this:

  1. Find a file somehow (NerdTree, Ctrl-P or :e the/file/path.txt)
  2. :SwitchCWDToSameAsCurrentFile (change working directory to same as the current file)
  3. Open NerdTree or :e . and go to the current working directory
  4. Add/Open a file from the current working directory
  • 3
    Does :e %:p:h do what you want? Nov 6, 2019 at 7:00
  • Yeah, kind of does. Impossible to remember, though :)
    – oligofren
    Nov 7, 2019 at 21:06
  • Well, you can map it away ;) Nov 8, 2019 at 9:56

3 Answers 3


:Ex<CR> followed by % will prompt you for a new filename in that directory, which can be a pretty smooth process.

Note that there's also set autochdir if that fits your patterns/plugins better (always change directory to match the current file).

  • 1
    That was pretty sweet, as it didn't actually rely on any plugins or similar. The lcd mapping and commands was probably more what I was looking for though, as that went well along with the CD shortcut in NERDTree for changing tree root to CWD. autochdir unfortunately didn't play nice along with NERDTree, as it just affected the current buffer/window (not sure about the terminology), not the new NT window. Good tip, anyhow!
    – oligofren
    Nov 7, 2019 at 21:04

SwitchCWDToSameAsCurrentFile (change working directory to same as the current file)

I use the following mapping:

nnoremap <Leader>= :lcd %:p:h \| pwd<CR>

Here are my edit in same directory mappings:

" Explore
nnoremap <silent> <Leader>ed :Explore<CR>
" Quickly input the directory of the current file on the command line
cnoremap <expr> %% filename#command_dir('%%')
" Need 'recursive' mapping here for %%
nmap <Leader>ew :e %%
nmap <Leader>ev :vs %%
nmap <Leader>es :sp %%
nmap <Leader>et :tabe %%

" Get the directory of a file
" - On Ex command lines, returns the directory of the file ('./' for new files)
" - On other command lines (/,?) returns the keymap used to trigger it
function! filename#command_dir(keymap) abort
  let l:command_type = getcmdtype()
  if l:command_type isnot# ':'
    return a:keymap
  let l:dir = expand('%:h')
  if empty(l:dir)
    let l:dir = '.'
  return l:dir . '/'

You can also then do :cd %% if you really need to change directories (and 'autochdir' can make that easier, as pointed out).

Honestly, I prefer to stay at the root project level most of the time though. It makes more sense in many ways. I have tools like ack, grep, git subcommands, and others which, combined with some bash functions and the quickfix list, make it easy to jump into vim at various parts of my code base. I’ll add them here later as needed.

  • I just got an error after putting that in my config: E746: Function name does not match script file name: filename#command_dir.
    – oligofren
    Nov 7, 2019 at 21:01
  • You’ll need to place that function in the autoload directory, apologies.
    – D. Ben Knoble
    Nov 7, 2019 at 22:12

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.