How to quickly change shell folder to match the currently open file

With single file opened in vscode, when I open integrated Powershell it always starts in my $HOME folder.

Is there any way to quickly switch to the directory of the currently shown file without having to manually cd into it?

Something like cd $vsCurrentFileDirectory.

Currently, I right click the tab and copy path then cd (Split-Path <CTRL-v>).


Solution 1:

EDIT: A new command will be added in v1.39 to make this more straightforward, see release notes. The example keybinding given is:

{
    "key": "cmd+shift+h",
    "command": "workbench.action.terminal.newWithCwd",
    "args": {
        "cwd": "${fileDirname}"
    }
}

which does indeed work in the Insider's Build. This will create a new terminal though, not modify an existing terminal.


[Original Answer]: This will change the current terminal.

You can set up a keybinding to do this pretty easily:

{
  "key": "alt+t",
  "command": "workbench.action.terminal.sendSequence",
  "args": {"text": "cd '${fileDirname}'\u000D"}
},

The \u000D is a return so the command triggers immediately.

Also note that I put the '${fileDirname}' in quotes in case your directory name has spaces in it.

The keybinding will work whether focus is in the terminal or the file.


Suggested edit to be tested :

Note that on windows, you must use the following instead:

"args": {"text": "cd /d \"${fileDirname}\"\u000D"}

This is because on Windows, the /d parameter must be used with cd to switch drives.


Also see shortcut to change directory in Powershell and cmd for additional info in case you are changing drive letters and escaping double quotes in Powershell.

{
    "key": "ctrl+alt+d",
    "command": "workbench.action.terminal.sendSequence",
    "args": {"text": "cd \"${fileDirname}\"\u000D"}
}

with discussion of the /d flag. Thanks to @skataben for the additional info.


Alternatively, there is an extension to do this: terminal-here, but the keybinding actually works faster. The sendSequence and variable substitution functionality was not available when that extension was created.

Finally, if you right-click on a folder in the explorer, there is an Open in Terminal option there (and corresponding command). Which means you could use that command in a keybinding like so:

{
  "key": "alt+t",
  "command": "openInTerminal"
}

But my first sendSequence keybinding remains the fastest way to do this.

Solution 2:

With Code Runner and Ctrl+Alt+N command you can have it solved by creating a batch file and passing the ${fileDirname} value to the PowerShell 6 e.g like this:

  1. Adding/changing those two lines in VSCode settings.json:

    "terminal.integrated.shell.windows": "C:\\Program Files\\PowerShell\\6\\pwsh.bat",
    "terminal.integrated.shellArgs.windows": ["${fileDirname}"]
    
  2. Having such a pwsh.bat saved in the C:\Program Files\PowerShell\6\ folder:

    @echo off
    set arg1=%1
    "C:\Program Files\PowerShell\6\pwsh.exe" -noexit -Command "cd '%arg1%'"
    

EDIT

Small improvement to the batch file code useful when no file is opened and we still want to open a new Terminal:

```
@echo off
set arg1=%1
if [%arg1%] == [${fileDirname}] set arg1=
"C:\Program Files\PowerShell\6\pwsh.exe" -noexit -Command "cd '%arg1%'"
```

Solution 3:

My solution was to simply add the following to VS Code Settings so that whatever key you have set for opening a new integrated terminal, it ensured that the terminal went to the directory of the currently opened file. This works regardless of the new terminal you select, be it powershell, CMD, Git Bash etc:

"terminal.integrated.cwd": "${fileDirname}"