12

When I edit file:

/home/me/projects/myproj/src/util.c

I would like to start terminal at:

/home/me/projects/myproj/src.

With Vim version > 8 I can run :terminal but it always starts at folder in which I've opened Vim (which is /home/me/projects/myproj)

How can I do this?

Vivian De Smedt
  • 16,336
  • 3
  • 18
  • 37
ephemerr
  • 833
  • 3
  • 8
  • 15

4 Answers4

15

I am grateful to @statox for useful hints, but as I don't wont to change current dir each time I come to following:

map <F6> :let $VIM_DIR=expand('%:p:h')<CR>:terminal<CR>cd $VIM_DIR<CR>
ephemerr
  • 833
  • 3
  • 8
  • 15
10

See :h :cd and :h :lcd.

:cd changes the current directory for all the windows while :lcd changes the current directory for the current window.

You can change the current directory to the directory containing the current file with:

:cd %:p:h

And you can use set autochdir in your .vimrc to change the current working directory whenever you open a file, switch buffers, delete a buffer or open/close a window. It will change to the directory containing the file which was opened or selected. (see :h 'autochdir')

Also note that the doc mentions that autochdir may break some plugin and this wikia page suggests the following autocommand to replace this setting:

autocmd BufEnter * silent! lcd %:p:h
statox
  • 49,782
  • 19
  • 148
  • 225
  • 1
    Note that when a local directory is in use for the current window, it's best to avoid :cd. When exists('*haslocaldir') && haslocaldir() is true, always use :lcd. Otherwise, we have the choice. – Luc Hermitte Dec 13 '17 at 13:29
  • 2
    Put it all together: split | lcd %:h | terminal ++curwin. May want to wrap this up into a command. e.g. command! -nargs=* Terminal split | lcd %:h | terminal ++curwin <args> – Peter Rincker Dec 13 '17 at 16:03
  • @PeterRincker With the ++curwin option to `terminal, it seems to be passing the "++curwin" as an argument to my shell rathe rthan opening the terminal in the current window – Thayne Oct 18 '22 at 20:34
  • According to :h :term: ++curwin is a valid option. Is it possible you are using an older version of Vim or maybe Neovim? – Peter Rincker Oct 19 '22 at 20:30
3

Building on the other answers, in neovim, you can do:

command! LocalTerm let s:term_dir=expand('%:p:h') | below new | call termopen([&shell], {'cwd': s:term_dir })

(this assumes that your shell is a single command with no options)

Thayne
  • 131
  • 4
0

You can use a Vim keymap with a single function. In my case, the leader is a space.

Short cut to open terminal Space+t.

What the Lua function does:

  1. It switches to directory of current file.
  2. Opens terminal on current file's directory.
  3. Switches to "insert" mode by itself.

The Lua function is as following:

vim.keymap.set("n", "<leader>t", function()
   vim.cmd("cd %:p:h")
   vim.cmd("terminal")
   vim.cmd("startinsert")
end)
  • This changes Vim's pwd, which as a side-effect is not present in other answers and might be worth highlighting as a tradeoff. – D. Ben Knoble Sep 06 '23 at 23:21