microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
95.82k stars 8.33k forks source link

Open new terminal tab in same directory as existing tab (OSC 7?) #3158

Open edencorbin opened 5 years ago

edencorbin commented 5 years ago

Description of the new feature/enhancement

Have the option (or default) of a new terminal tab opening in the current directory of the window of which you hit the hotkey to open a new tab. This is the standard way most linux terminals work and is most handy. I often work in a directory where I need to launch multiple seperate processes, its a pain to CD back into the directory each time.

Proposed technical implementation details (optional)

Hit the new tab hotkey, the new terminal should then be in the same folder as the previouse.


maintainer edit: Before commenting, make sure to check out

Tutorial: Opening a tab or pane in the same directory in Windows Terminal

This is largely something configurable today, this issue is just tracking another way of configuring this

LuanVSO commented 3 years ago

@saschanaz probably, you will get a better shot on psreadline repo. but it's pretty easy to DIY, just put this in your $profile

function prompt {
        $p = $pwd.ProviderPath
    # $ansi_escape = [char]27 on powershell 5.1 replace "`e" whith this variable
    Write-host "`e]9;9;$p`e\" -NoNewline    
    "PS $p$('>' * ($nestedPromptLevel + 1)) "
}
TBBle commented 3 years ago

So now that this is working for duplicate tab and split pane w/duplicate, I'd like it for "new tab", as per the original request. Probably as a parameter for the newTab action, not a change in the default. My use-case is that sometimes I'm in a directory in PowerShell, and I want "Git Bash here".

Should I open a new issue for that request, or is that in-scope for this one as further work after #8330?

I also noticed that the default keybindings for splitPane (alt+shift+- and alt+shift+plus) do not get this behaviour, because they are using the default splitMode, 'Manual', which launches the default shell due to lack of other parameters. I guess it might be surprising for users that a 'Manual' splitPane that picks the same profile as my current terminal, is different from a 'Duplicate' splitPane. It certainly surprised me. ^_^

(Side-note: Should the default splitPane keybinding be Duplicate rather than Manual? I guess Manual is consistent with the default newTab keybinding... Now I know this, I'm locally overriding those splitPane default keys to be Duplicate)

It's possible that for what I want, a magic token for the startingDirectory parameter of the splitPane and newTab actions would be sufficient, but personally I'd lean towards a boolean field for copyWorkingDirectory, except that this might incorrectly set the expectation that it "just works" without the current shell calling OSC 9;9 (or OSC 7 etc. in future).

A magic token could be explicitly tied to "the directory set by OSC 9;9 or OSC 7, see the WT OSC docs for details".

ojroques commented 3 years ago

It wasn't clear to me how to enable OSC 9;9 for WSL but I've finally figured it out. You should put this line in your .bashrc:

export PROMPT_COMMAND='printf "\e]9;9;%s\e\\" "$(wslpath -m "$PWD")"'
TBBle commented 3 years ago

If anyone is using PowerLine, this is what I'm using in the Prompt array of ${ENV:AppData}\powershell\HuddledMasses.org\PowerLine\Configuration.psd1 to generate OSC 9;9, as well as output the current directory:

(ScriptBlock ' New-PromptText { "&OSC;9;9;"+$executionContext.SessionState.Path.CurrentLocation+"&ST;" + $executionContext.SessionState.Path.CurrentLocation } -ForegroundColor DarkYellow ')

I've added the last two escape sequences as well:

  EscapeSequences    = @{
    Esc    = '['
    Store  = ''
    Recall = ''
    Clear  = ''
    OSC    = ']'
    ST     = '\'
  }

Each of those lines has the same character at the start. I just copied the 'Esc' line (really should be "CSI", I think), changed the non-hidden character, and the name.

My whole Configuration.psd1 file for context Originally generated with `Export-PowerLinePrompt` and then modified as the mood hit me. ```Powershell @{ ExtendedCharacters = @{ ColorSeparator = '' ReverseColorSeparator = '' Separator = '' ReverseSeparator = '' Branch = '' Lock = '' Gear = '⛯' Power = '⚡' } PowerLineConfig = @{ RestoreVirtualTerminal = $True Prompt = @((ScriptBlock ' New-PromptText { "&OSC;9;9;"+$executionContext.SessionState.Path.CurrentLocation+"&ST;" + $executionContext.SessionState.Path.CurrentLocation } -ForegroundColor DarkYellow '), (ScriptBlock ' "`t" '), (ScriptBlock ' Write-VcsStatus '), (ScriptBlock ' "`n" '), (ScriptBlock ' New-PromptText { ">" * ($NestedPromptLevel + 1) } -ForegroundColor Blue -ElevatedForegroundColor Yellow ')) Colors = @((RgbColor 'Black'), (RgbColor 'Black'), (RgbColor 'Black')) PowerLineFont = $True FullColor = $True DefaultAddIndex = 2 SetCurrentDirectory = $True } EscapeSequences = @{ Esc = '[' Store = '' Recall = '' Clear = '' OSC = ']' ST = '\' } } ```
s-celles commented 3 years ago

As suggested in #9063, here is an other UI proposition for such a feature.

Proposed technical implementation details (optional)

Right click on a tab could have a "New" contextual menu (between rename tab and close) which could show same entries as those in the "+" tab.

The main difference would be that a new tab will be created with the "context" of a tab which was opened previously (context being here the current working directory)

paulvandenburg commented 3 years ago

It wasn't clear to me how to enable OSC 9;9 for WSL but I've finally figured it out. You should put this line in your .bashrc:

export PROMPT_COMMAND='printf "\e]9;9;%s\e\\" "$(wslpath -m "$PWD")"'

If you tried this and it didn't work, it could be that you're running the stable version of terminal which doesn't have this yet. You can get the preview version from the store: https://www.microsoft.com/store/productId/9N8G5RFZ9XK3
Just confirmed it working for WSL 😃

gemboj commented 3 years ago

It wasn't clear to me how to enable OSC 9;9 for WSL but I've finally figured it out. You should put this line in your .bashrc:

export PROMPT_COMMAND='printf "\e]9;9;%s\e\\" "$(wslpath -m "$PWD")"'

If you tried this and it didn't work, it could be that you're running the stable version of terminal which doesn't have this yet. You can get the preview version from the store: https://www.microsoft.com/store/productId/9N8G5RFZ9XK3 Just confirmed it working for WSL 😃

I have a very strange issue with this solution. I've installed Ubuntu 20.04, put the export into my .bashrc and as expected, it started working. I've then played around, installed some additional packages into my ubuntu and reinstalled whole distro Ubuntu 20.04 from microsoft store a few times, to reset clean my wsl.

At some point, I've noticed that this trick stopped working. No matter what I do, the windows terminal no longer has the ability to properly set the directory for a new tab to match the existing tab. I've tried everything that came to my mind: reinstalling windows terminal, reinstaling all the linux distributions, installing additional distributions (Ubuntu 18.04, openSUSE Leap 15.2), reinstalling linux kernel update package, disabling and reenabling the wsl from windows features, and updating my Windows version. Nothing works.

I've no idea how to debug the issue. Is this some wsl problem? Windows terminal problem? How to make sure that everything is properly cleaned up before reinstalling everything?

Operating System info

Additional info

LuanVSO commented 3 years ago

put

    "debugFeatures": true,

in the global settings for windows terminal then hold down both alt keys and open the profile that you are having problems, should look something like this: image verify if osc9;9 is being emitted

mnpenner commented 3 years ago

Anyone happen to know how to add OSC 9;9 to Powerlevel10K (zsh)? I don't think export PROMPT_COMMAND= works.

LuanVSO commented 3 years ago

here:

 __wt_osc9_9 () {
      _win_path=$(wslpath -m "$(pwd)")
      printf "\033]9;9;\"%s\"\033\\" "$_win_path"
  }

  [ -n "$BASH_VERSION" ] && [ -n "$WT_SESSION" ] && PROMPT_COMMAND="__wt_osc9_9"
  [ -n "$ZSH_VERSION"  ] && [ -n "$WT_SESSION" ] && precmd_functions+=(__wt_osc9_9)

put it in a file and then source it from .zshrc or .bashrc

gemboj commented 3 years ago

put

    "debugFeatures": true,

After turning on the debugFeatures I got the following result: image

The 9;9;//wsl$/Ubuntu-20.04/home/gemboj before my prompt (which is not visible in the non debugging terminal) tells me that the osc9;9 is properly emitted. Still, the directory of a new tab is not set properly.

zadjii-msft commented 3 years ago

@gemboj Just to be sure, you're using a duplicateTab action/keybinding to attempt to duplicate the tab, right?

gemboj commented 3 years ago

@gemboj Just to be sure, you're using a duplicateTab action/keybinding to attempt to duplicate the tab, right?

Okay. This is the moment I want to curl up and die. At some point my muscle memory must have kicked in and I started using ctrl+shift+t (new tab) instead of duplicating the current tab. At least I've learned the neat trick with debugFeatures. Now to never come back here out of embarrassment...

catweazle9 commented 3 years ago
  [ -n "$ZSH_VERSION"  ] && [ -n "$WT_SESSION" ] && precmd_functions+=(__wt_osc9_9)

Putting the above in my .zshrc meant the function was re-added each time I sourced .zshrc, and I think I noticed a slowdown in showing the prompt that worsens for each occurrence. To limit this to one instance I tweaked it slightly to this:

if [ -n "$WT_SESSION" ] ; then
    if ((!precmd_functions[(I)__wt_osc9_9])); then
        precmd_functions+=(__wt_osc9_9)
    fi
fi
omar-toma commented 3 years ago

I confirm that @ojroques's solution works for me on wsl

If you are using fish shell like me, I managed to make make it work by adding a new file in ~/.config/fish/conf.d for ex. windows-terminal.fish and added this to it

function windows-terminal --on-event fish_prompt
    printf "\e]9;9;%s\e\\" (wslpath -m "$PWD")
end
robsonsobral commented 3 years ago

I just added this to my $profile without luck:

function prompt
{
  $loc = Get-Location

  # Emulate standard PS prompt with location followed by ">"
  $out = "PS $loc> "

  # Add current working directory (FileSystem)
  if ($loc.Provider.Name -eq "FileSystem") {
    $out += "$([char]27)]9;9;`"$($loc.Path)`"$([char]7)"
  }

  return $out
}

Running the new v1.6.10571.0 on Windows 10

LuanVSO commented 3 years ago

@robsonsobral here: https://gist.github.com/LuanVSO/6f2b94cf3bd90f184722676c43ccc1c6

robsonsobral commented 3 years ago

Thank you, @LuanVSO ! It worked!

I also had to move PSHAZZ script to the top of the file. Actually, pshazz block the script to run. It has to be removed.

try { $null = gcm pshazz -ea stop; pshazz init } catch { }
TBBle commented 3 years ago

A brief look at pshazz's prompt management suggests that you could write a plugin something like the z plugin to act on each prompt-display and call the Write-Host you want (i.e. the first three lines of the prompt function from @LuanVSO), although you have to activate the plugin in your preferred theme, I assume.

Otherwise, perhaps modify global:pshazz_write_prompt, to call Write-Host with the relevant values irrespective of theme.

robsonsobral commented 3 years ago

Thank you, @TBBle ! It worked!

image

I already wrote a plugin to customize things. So I added:

Import-Module "$pluginDir\z"
Set-Alias z Search-NavigationHistory -Scope "global"
function global:pshazz:z:prompt {
    $esc=[char]27
    $p = $pwd.ProviderPath
    Write-host "$esc]9;9;`"$p`"$esc\" -NoNewline
}

Thank you so much!

Evineit commented 3 years ago

I was having trouble getting to work the new duplicate tab in the same directory, after adding the code to my PowerShell profile now it seems to be working fine and the OSC9;9 is added, i don't know why this was happening. I added both images of the debug terminal before and after adding the function.

function prompt {
        $p = $pwd.ProviderPath
  # $ansi_escape = [char]27 on powershell 5.1 replace "`e" whith this variable
  Write-host "`e]9;9;$p`e\" -NoNewline    
  "PS $p$('>' * ($nestedPromptLevel + 1)) "
}

Before This is before using your script

After This is after using your script

Thank you, @LuanVSO!

LuanVSO commented 3 years ago

that's because PowerShell by default does not emit the required escape esquece for it to work

merrijo commented 3 years ago

Has anyone gotten OSC9;9 to work with Windows CMD? I tried the setx example above, but it didn't work...

I also noticed some weird behavior in Powershell 7.1, but I don't know if this is the best place to ask. When I pipe a command I start seeing OSC9;9 outputs, for example:

PS C:\code\online_repos\terminal> git branch | grep ^\*
* main
PS C:\code\online_repos\terminal> ←]9;9;"C:\code\online_repos\terminal"

Has anyone else seen this behavior?

LuanVSO commented 3 years ago

I also noticed some weird behavior in Powershell 7.1, but I don't know if this is the best place to ask. When I pipe a command I start seeing OSC9;9 outputs, for example:

PS C:\code\online_repos\terminal> git branch | grep ^\*
* main
PS C:\code\online_repos\terminal> ←]9;9;"C:\code\online_repos\terminal"

Has anyone else seen this behavior?

that's because the git for windows commands explicitly disables vt processing and powershell doesn't turn it back on when native commands exit, this was resolved in the latest powershell 7.2 preview

LuanVSO commented 3 years ago

Has anyone gotten OSC9;9 to work with Windows CMD? I tried the setx example above, but it didn't work...

https://gist.github.com/LuanVSO/09ba0239fe7c1a959a9b07c7156c5e13

patricknelson commented 3 years ago

For anyone looking for a workaround that is nearly as good (but not exactly the same), there is an alternative approach. Instead of maintaining the current working directory, you can at least ensure that new tabs and panes open in the same starting directory (since current will vary over time).

Alternative steps:

  1. Use the custom right-click integration by BroJenuel/Explorer-Context-Menu-Integration-for-windows-terminal (which isn't subject to the separate but related bug documented in #8933).
  2. Since that creates a duplicate right-click entry, remove it by using the fix documented here: https://github.com/microsoft/terminal/issues/7008#issuecomment-662621638, or drop this into a .reg file and run it:

    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked]
    "{9F156763-7844-4DC4-B2B1-901F640F5155}"="WindowsTerminal"

End result is that it will at least persist the same starting directory (albeit it will not be up-to-date with cd changes, which is really what this issue is about).

Demo:

2021-03-18_18-34-07

merrijo commented 3 years ago

Has anyone gotten OSC9;9 to work with Windows CMD? I tried the setx example above, but it didn't work...

https://gist.github.com/LuanVSO/09ba0239fe7c1a959a9b07c7156c5e13

Thanks for this, however it doesn't work for me. The split panes always open in my default user path.

I also noticed some weird behavior in Powershell 7.1, but I don't know if this is the best place to ask. When I pipe a command I start seeing OSC9;9 outputs, for example:

PS C:\code\online_repos\terminal> git branch | grep ^\*
* main
PS C:\code\online_repos\terminal> ←]9;9;"C:\code\online_repos\terminal"

Has anyone else seen this behavior?

that's because the git for windows commands explicitly disables vt processing and powershell doesn't turn it back on when native commands exit, this was resolved in the latest powershell 7.2 preview

Aha, thanks for clarifying! I'll test the latest Powershell 7.2 preview.

skyline75489 commented 3 years ago

@joshmer Remember to use "duplicate pane" instead of "new pane". Only by duplicating a pane, you'll have the same CWD in the new pane.

merrijo commented 3 years ago

Duplicate pane is alt+shift+d correct? That's what I'm using. Here's a snippet from my settings file to confirm: image

skyline75489 commented 3 years ago

@joshmer Yes. Seems like you're doing the right thing. The setx thing works for me in plain CMD. But it doesn't work for like VS Developer Command Prompt for some reason. Are you also trying to make it work for Developer Command Prompt or something?

LuanVSO commented 3 years ago

@joshmer could you also try this steps please

merrijo commented 3 years ago

@joshmer Yes. Seems like you're doing the right thing. The setx thing works for me in plain CMD. But it doesn't work for like VS Developer Command Prompt for some reason. Are you also trying to make it work for Developer Command Prompt or something?

Nope, I'm using standard CMD via Windows Terminal.

@joshmer could you also try this steps please

Edit: Apologies, I wasn't holding both ALT keys!

␛[?9001h␛[18;56;0;1;259;1_␛[2J␛[m␛[HMicrosoft␣Windows␣[Version␣10.0.19042.867]␛]0;Command␣Prompt␇␛[?25h␍␊(c)␣2020␣Microsoft␣Corporation.␣All␣rights␣reserved.␍␊␛]0;Command␣Prompt␣-␣"C:\Program␣Files␣(x86)\clink\0.4.9\clink.bat"␣␣inject␣--autorun␣--profile␣~\clink␇␛[18;56;0;1;259;1_␛[18;56;0;1;259;1_␛[18;56;0;1;259;1_␛[18;56;0;1;259;1_␛[18;56;0;1;259;1_␛[?25lClink␣v0.4.9␣[git:2fd2c2]␣Copyright␣(c)␣2012-2016␣Martin␣Ridgers␍␊http://mridgers.github.io/clink␛[6;1H␛[?25h␛[18;56;0;1;259;1_␛[18;56;0;1;259;1_␛]0;Command␣Prompt␇␛[18;56;0;1;259;1_␍␊␛]0;Administrator:␣Command␣Prompt␇␛[18;56;0;1;259;1_

I also have clink and MSYS2 setup in my system, so maybe something there is messing with things?

skyline75489 commented 3 years ago

OK I see clink.bat and related things in it. Guess that's the cause, since it's working fine in plain CMD. Perhaps this is the same reason why VS Developer Command Prompt doesn't work.

Unfortunately I'm no expert at CMD. I hope someone could shed light on this topic.

DHowett commented 3 years ago

Is there a chance vsdevcmd just ... overrides the directory on startup?

DHowett commented 3 years ago

Actually, yeah, the only OSC I'm seeing in that trace is OSC 0 (set title). There's something stripping it out before it gets printed.

merrijo commented 3 years ago

Ok, so I tried to rename all vsdevcmd.bat files to prevent them from doing anything, and it didn't work. Then I uninstalled clink and I'm now getting the correct OSC prompts! I reverted the vsdevcmd file names and it's still working fine.

As a sanity check I reinstalled clink and OSC is broken again, so I'll have to do some digging into what's happening there. Thanks all for the help!

TBBle commented 3 years ago

I was just poking around in the Clink source, and it seems like it should be passing OSC codes through but it definitely has code to parse then, e.g., 0.4.9, 1.0.0a1, and I suspect that it's locally handling them to generate Console API calls, and hence stripping them even if it doesn't handle them.

So possibly (although I couldn't find this code in 0.4.9 as GitHub has indexed after a refactoring) it's only passing through recognised codes, and OSC 9;9 isn't recognised yet.

Either way, sounds like a bug report for clink is in-order here.

piradata commented 3 years ago

TL;DR

For the ones reading this right now that wants this behaviour on windows terminal WSL, just add the following line on your ~/.bashrc file:

export PROMPT_COMMAND='printf "\e]9;9;%s\e\\" "$(wslpath -m "$PWD")"'

Then the terminal will maintain the path when you press "Alt+Shift+D", but when you split with "Alt+Shift+-" or "Alt+Shift+=" it will open with the standard path, and that is pretty ok in my opinion. To configure the standard path to be your wsl home directory, edit your setting of WSL profile to be something like this:

{ "guid": "{2c4de342-38b7-51cf-b940-2309a097f518}", "name": "Ubuntu", "source": "Windows.Terminal.Wsl", "startingDirectory": "\\\\wsl$\\Ubuntu\\home\\<Your_User>", "hidden": false }

Cheers!!

JCMais commented 3 years ago

Is it currently possible to pass split mode to the wt CLI?

DHowett commented 3 years ago

Is it currently possible to pass split mode to the wt CLI?

Yes.

zadjii-msft commented 3 years ago

Actually that might not be right - you can pass the split direction but the splitMode is always manual

JCMais commented 3 years ago

@zadjii-msft do you want me to open a new issue with that feature request or that is not needed? 😄

zadjii-msft commented 3 years ago

Nope, I already filed one 😉

tignioj commented 3 years ago

I've come with a workaround: change the starting directory.

Put this function into $PROFILE (make sure to adjust $path)

function sd {
    $path = 'C:\Users\Admin\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json'
     ((Get-Content -path $path) -replace '"startingDirectory":.*', ("`"startingDirectory`": `"$pwd`"") -replace "\\", "\\") | Set-Content -Path $path
}

.. and you'll be able to a open new tab in the same directory almost with no hassle, just make sure to type sd before opening a new tab.

Of course, the drawback is that startingDirectory is changed every time the function is called.

It would be best to use this approach with a key re-mapper, so that when Ctrl+T is pressed the function is called automatically, and when Ctrl+F4 is pressed startingDirectory is reverted back to its original value.

Thanks for you, I have made some changes to the code to accommodate those with commas after them, It work's for me!

function sdd {
  $path = "$env:USERPROFILE\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" 
  $todir = ("$pwd") -replace "\\","\\"  
   ((Get-Content -path $path)  -replace '("startingDirectory":)(.*")(.*)', ("`$1`"$todir`"`$3")) | Set-Content -Path $path
}
ropbastos commented 3 years ago

@robsonsobral here: https://gist.github.com/LuanVSO/6f2b94cf3bd90f184722676c43ccc1c6

Many thanks for that, been wanting that feature for ages!

Unfortunately, it seems to break Chocolatey/Scoop. After installing programs with them the PATH seems to not be edited anymore. I just pasted that on my $profile, am I missing something?

LuanVSO commented 3 years ago

Many thanks for that, been wanting that feature for ages!

Unfortunately, it seems to break Chocolatey/Scoop. After installing programs with them the PATH seems to not be edited anymore. I just pasted that on my $profile, am I missing something?

@ropbastos do you mean that the refreshenv doesn't work anymore? could you share the contents of your $profile please?

ropbastos commented 3 years ago

My bad, I don't really know what went on when I made that comment. I remember running "choco install nodejs" and not having node show on path but I just tried to reproduce it and, happily, I guess x), failed. It works perfectly it seems, sorry! And many thanks to all contributors here!

tg21 commented 3 years ago

I am able to replicate Panes and tabs(with same working directory) in windows terminal using these steps.

  1. obtained terminal context menu item using this library Windows-terminal-context-menu. For some reason it does not work with default context menu option image

  2. set Starting directory of all profiles to "use parent process directory" image

  3. this is my key-mapping for split-pane { "command": { "action": "splitPane", "split": "auto", "splitMode": "duplicate" }, "keys": [ "alt+shift+d" ] },

  4. Result image

This works for tabs as well.

I hope this helps.\ maybe devs can see how differently this library is making context menu options.\ let me know if you need some more details.\

Known issues with this workaround
TBBle commented 3 years ago

That approach is no different to just going into the directory in a console, and running Terminal from there.

It doesn't help this ticket at all, which is for this:

Still does not keep the CWD same if you change it after opening the terminal. but will keep the initial directory(from where terminal was opened) as CWD.

It won't interfere with it though, so if you then add "OSC9;9" to your various shells, then 'duplicate' and 'split-Duplicate' will work, but 'New tab' and 'split-new' are still to be done.

That said, that's a clever shell extension idea that solves a different, related problem.

tg21 commented 3 years ago

Yes you are absolutely correct. while mentioning known issues in my workaround I realized this wasn't exactly what this thread was about. But because almost all issues mentioning duplicate tabs/panes with same directory are marked duplicate of #3158 and closed. I thought I would leave it here for some like me willing to make do with this solution in the meantime.