microsoft / terminal

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

Ctrl-backspace does not delete back to the previous wordbreak #755

Closed DHowett-MSFT closed 4 years ago

DHowett-MSFT commented 5 years ago

It deletes character-by-character instead.

Kapperchino commented 5 years ago

I don't see the keybinding in the terminal app, it might not be implemented.

DHowett-MSFT commented 5 years ago

@kapperchino More to the point, though, is that Ctrl+Backspace is a VT sequence that needs to be serialized and sent to the application on the other end... it's not likely to be rebindable or otherwise treated as a key binding.

vapier commented 5 years ago

you just want to make sure the right sequence is sent to the foreground program in the terminal right? the job of deleting words is handled by the shell rather than the terminal since the terminal has no concept of words, only cells.

DHowett-MSFT commented 5 years ago

Yes.


From: Mike Frysinger notifications@github.com Sent: Tuesday, May 14, 2019 2:19:01 PM To: microsoft/Terminal Cc: Dustin Howett; Author Subject: Re: [microsoft/Terminal] Ctrl-backspace does not delete back to the previous wordbreak (#755)

you just want to make sure the right sequence is sent to the foreground program in the terminal right? the job of deleting words is handled by the shell rather than the terminal since the terminal has no concept of words, only cells.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FTerminal%2Fissues%2F755%3Femail_source%3Dnotifications%26email_token%3DADNHLGSJTE4KKXWHDECROFDPVMUELA5CNFSM4HMTV4DKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVM2FPI%23issuecomment-492413629&data=01%7C01%7Cduhowett%40microsoft.com%7C1997e6ff518e4a3f396708d6d8b1c987%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=V1y3C26WGNZ50VnZW5BhV1CYKetf%2BgGLqov9Sc9tLw0%3D&reserved=0, or mute the threadhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FADNHLGQKRNJQTZBZCRAZMO3PVMUELANCNFSM4HMTV4DA&data=01%7C01%7Cduhowett%40microsoft.com%7C1997e6ff518e4a3f396708d6d8b1c987%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=auF20gJCIvXV%2FYpDN0e%2B3JzvxI766ZTbszhk3qx%2BwUo%3D&reserved=0.

Summon528 commented 5 years ago

FYI, if you launch PowerShell through WSL, ctrl + backspace will also delete character-by-character, so this is probably not Terminal's problem.

Summon528 commented 5 years ago

Apparently Ctrl + backspace == <U+0008> == ^H which most shells including PowerShell treated as delete one char, so this is kind of by design? Also, this is probably why most Linux shells use Alt + backspace instead

zadjii-msft commented 5 years ago

Yea this might be a PSReadline thing TBH. I bet they're looking for an INPUT_RECORD with ctrl+backspace, but as @Summon528 mentioned, we're sending ^H, which is what most terminal emulators will send for ctrl+backspace.

Then, when conpty recieves the ^H, it will translate that to: image

as opposed to image

This might be solvable with the whole conpty INPUT_RECORD thing

gohar94 commented 5 years ago

Regular PowerShell does delete back till previous wordbreak so I'd expect the PowerShell tabs in Windows Terminal to do the same.

DHowett-MSFT commented 5 years ago

"I'd expect"

good, that's why this is a bug that's still open and not resolved as By Design

rkeithhill commented 5 years ago

@lzybkr @daxian-dbw Any thoughts on this? It is a bummer that ctrl+backspace doesn't work when PS Core runs in Windows Terminal. FWIW this is also an issue with cmd.exe.

lzybkr commented 5 years ago

I don't have a solution, but on Windows, PSReadLine relies on the CLR to map INPUT_RECORDs with more precision than what you typically get with non-Windows terminals. There is also a related platform specific assumption being made here:

https://github.com/PowerShell/PSReadLine/blob/f2f553156063a8635b9d4882a878a828365cdd99/PSReadLine/Keys.cs#L291

richardszalay commented 5 years ago

FWIW, you can workaround this problem by press CTRL+SHIFT+LEFT (which selects the previous word) and then pressing backspace. It's far from ideal, but it's more efficient than backspaces through the individual characters.

JakeShirley commented 5 years ago

I'd also love to see this fixed! Definitely a jarring change from using regular PowerShell.

awhewell commented 5 years ago

Just to be clear, this is not only an issue with powershell tabs. I originally came here to report it not working on cmd.exe tabs.

Moreover the CTRL+SHIFT+LEFT workaround does not work in cmd.exe tabs. If you type "foo" and then CTRL+SHIFT_LEFT then it just moves the cursor to the start of "foo". It does not select the word so pressing backspace does not then have the desired effect.

williamclot commented 5 years ago

I'm using zsh as my shell in WSL. When using bindkey '^H' backward-kill-word I get the expected behavior.

This is my configuration:

bindkey -e
# Control + backspace
bindkey '^H' backward-kill-word
# Control + arrows
bindkey ";5C" forward-word
bindkey ";5D" backward-word
yggdrasil75 commented 5 years ago

I would like to note on this issue that almost every program by microsoft, as well as most external programs use control+backspace to delete the entire word, however it is not for some reason a native windows function, which means that each of those programs either have to manually add support for the functionality, or their compiler does it for them. This is such a standard function that it is expected to occur everywhere by people who know hotkeys, would it not be more prudent to add it as a native windows function than to just update the various terminals?

(side note: explorer.exe also inserts ascii 127 - delete character instead of deleting the entire word)

jnm2 commented 5 years ago

Some history on Ctrl+Backspace: https://devblogs.microsoft.com/oldnewthing/?p=24823

jevring commented 5 years ago

Use bind '"\C-H":backward-kill-word' in bash to solve this issue.

Geogboe commented 4 years ago

Definitely agree @yggdrasil75 that pretty every text editor/browser supports this, along with cmd.exe and powershell.exe and even notepad in the latest windows builds.

This is a big blocker for me, especially since I use powershell and powershell cmdlets/params can get long. Having to use basic backspace or select previous word and then backspace just breaks up my workflow too much.

For anyone else who is using autohotkey I just wanted to throw out that this simple macro will allow you to workaround this until it's implemented.

#SingleInstance force ; Automatically overwrite any running instance of this script
#Persistent ; If this directive is present anywhere in the script, that script will stay running after the auto-execute section (top part of the script) completes

; For Windows Terminal - deletes the previous word
#IfWinActive ahk_exe WindowsTerminal.exe ; Wait for WindowsTerminal to be active
^backspace::
    Send, ^+{Left}
    Send, {Delete}
return

It sucks having something like this always running but I'm only going this route because of how much I love all other aspects of terminal and this is the final piece that makes this the perfect terminal for me.

paulelms commented 4 years ago

Fix for PSReadLine: Set-PSReadLineKeyHandler -Key Ctrl+h -Function BackwardKillWord

decoyjoe commented 4 years ago

Definitely agree @yggdrasil75 that pretty every text editor/browser supports this, along with cmd.exe and powershell.exe and even notepad in the latest windows builds.

This is a big blocker for me, especially since I use powershell and powershell cmdlets/params can get long. Having to use basic backspace or select previous word and then backspace just breaks up my workflow too much.

For anyone else who is using autohotkey I just wanted to throw out that this simple macro will allow you to workaround this until it's implemented.

#SingleInstance force ; Automatically overwrite any running instance of this script
#Persistent ; If this directive is present anywhere in the script, that script will stay running after the auto-execute section (top part of the script) completes

; For Windows Terminal - deletes the previous word
#IfWinActive ahk_exe WindowsTerminal.exe ; Wait for WindowsTerminal to be active
^backspace::
    Send, ^+{Left}
    Send, {Delete}
return

It sucks having something like this always running but I'm only going this route because of how much I love all other aspects of terminal and this is the final piece that makes this the perfect terminal for me.

Be sure to turn off context sensitivity with #IfWinActive directly after this if you use any other hotkeys in your AHK script, otherwise any hotkeys defined below it will only apply when ahk_exe WindowsTerminal.exe is active.

; For Windows Terminal - deletes the previous word
#IfWinActive ahk_exe WindowsTerminal.exe ; only apply to this active window
^backspace::
    Send, ^+{Left}
    Send, {Delete}
return
#IfWinActive ; turns off context sensitivity
CindyKee commented 4 years ago

Fix for PSReadLine: Set-PSReadLineKeyHandler -Key Ctrl+h -Function BackwardKillWord

Thank you so much for this, @paulelms ! It works great in my PowerShell/Core windows, which I use the most! Awesome!🥇

TylerLeonhardt commented 4 years ago

We had to do something similar for vscode's terminal.

if ($env:TERM_PROGRAM -eq "vscode") {
    Set-PSReadLineKeyHandler -Chord 'Ctrl+w' -Function BackwardKillWord
    Set-PSReadLineKeyHandler -Chord 'Alt+D' -Function KillWord
    Set-PSReadLineKeyHandler -Chord 'Ctrl+@' -Function MenuComplete    
}

Ctrl+Backspace gave us Ctrl+w Ctrl+Spacebar gave us Ctrl+@

I actually added these as default keybindings in PSReadLine since vscode was such a common scenario.

Perhaps some alignment with them (aka xterm.js) is worth it for everyone?

Kralizek commented 4 years ago

We had to do something similar for vscode's terminal.

if ($env:TERM_PROGRAM -eq "vscode") {
    Set-PSReadLineKeyHandler -Chord 'Ctrl+w' -Function BackwardKillWord
    Set-PSReadLineKeyHandler -Chord 'Alt+D' -Function KillWord
    Set-PSReadLineKeyHandler -Chord 'Ctrl+@' -Function MenuComplete    
}

Ctrl+Backspace gave us Ctrl+w Ctrl+Spacebar gave us Ctrl+@

I actually added these as default keybindings in PSReadLine since vscode was such a common scenario.

Perhaps some alignment with them (aka xterm.js) is worth it for everyone?

we can use WT_SESSION from #2256 to understand if we are in Windows Terminal.

billgr commented 4 years ago

I've tried to use Terminal. I didn't realize how much I needed Ctrl+Backspace. I lasted about 2 hours and had to give up. I'll try again after this gets addressed.

TylerLeonhardt commented 4 years ago

@billgr did you try the workaround?

mahmoudajawad commented 4 years ago

@TylerLeonhardt, can you explain how to implement this workaround? I ran it in PS, as well as in $PROFILE but with no luck.

Kralizek commented 4 years ago

@TylerLeonhardt, can you explain how to implement this workaround? I ran it in PS, as well as in $PROFILE but with no luck.

Assuming you have psreadline installed, I have this snippet added into my $PROFILE.CurrentUserAllHosts

if ($env:WT_SESSION -ne $null)
{
    Set-PSReadLineKeyHandler -Key Ctrl+h -Function BackwardKillWord
}

This is a very rough solution but it works for me :)

mahmoudajawad commented 4 years ago

@Kralizek, thanks a lot. For some reasons it went the "It doesn't work for me, It works for you, and, now it works for me as well" scenario.

I'm glad this works now. But since you folks already tested this I'm pretty sure you are aware this doesn't work in WSL, right? And using:

stty werase ^H

will do the trick for WSL as well.

mkitzan commented 4 years ago

@DHowett-MSFT I'm interested in implementing this and maybe Ctrl+Del while I'm at it. Any tips on starting? I haven't dug too deep into the VirtualTerminal part of WT.

DHowett-MSFT commented 4 years ago

@mkitzan sure! Here's the parts you'll want to look at.

The thing you'll need to care about is how VirtualTerminalInput is used between 0 and 2 times for every given piece of non-standard-character input.

mkitzan commented 4 years ago

Great, I'll look into this. Thanks.

mkitzan commented 4 years ago

Update: ESC\0x8 does what we want in WSL, but not in PS or CMD. Ctrl+Del works correctly out of the box in PS, but not in WSL or CMD. Still a work in progress ⛑. For WSL power users (w/ a dev build) in the thread looking for a quick fix, replace L"\x8" to L"\x1b\x8". For WSL preview build folks, Alt+Ctrl+Backspace will do what you want out the box (sub-optimal as it is). Actual footage of reaching conpty boundary during code tracing. conpty-boundary

travisterrell commented 4 years ago

I want to give a thumbs-up for implementing this issue. It is a pretty standard shortcut, and has been present in the other windows shell emulators since...pretty much forever.

The PSReadLine and AHK solutions are fine, but I don't suppose there is any possibility of implementing this via a profiles.json shortcut? (i.e. "command": "something", "keys": [ "ctrl+backspace" ]

I would assume not, since this setting seems to be primarily used for keymapping existing commands.

DHowett-MSFT commented 4 years ago

via a profiles.json shortcut

At its core, a terminal is a way to get text from one place to another. There is no command we can implement on the terminal side that will make a remote shell understand that we want to delete a whole word.

Our only option is to make sure we can pass through Ctrl+Backspace in a way the remote shell can understand.

mkitzan commented 4 years ago

Got one message for all the good people in the thread we-got-him

@zadjii-msft your comment was very helpful. Essentially just needed to reinterpret how InputStateMachine processes \b as a control character. I've also got small fixes to two other issues on my working branch. Do you mind if I make one PR which includes all three fixes, or would you prefer separate PRs for each?

ghost commented 4 years ago

:tada:This issue was addressed in #3935, which has now been successfully released as Windows Terminal Preview v0.8.10261.0.:tada:

Handy links:

Nufflee commented 4 years ago

This issue still doesn't seem to be fixed in WSL1 terminals. Ctrl+Backspace doesn't work in a vanilla WSL1 terminal without the "bind" command provided earlier in this thread. Am I doing something wrong or does this still not work across all terminals?

jevring commented 4 years ago

@Nufflee even that bind command doesn't necessarily work in wsl1 anymore. It works on some machine, but not others. The one that does seem to work on all my machines right now is this: stty werase ^H

Ensuperb commented 4 years ago

thx @jevring , it works for my bash

lucky-wolf commented 4 years ago

I don't get it... ctrl+backspace doesn't delete word through ssh in a "Windows Terminal" (beta). This functionality works if I use a terminal window through my linux VM. In fact, Ctrl+BS works in all windows in linux env., whether I'm remote shelled in or locally. It's a fairly universal keybinding in linux.

But for Windows Terminal - Ctrl+BS, Shift+BS, Ctrl+Shift+BS, Ctrl+Alt+BS, Alt+BS, etc. - every possible combo - does not a damn thing.

Is there some way to say "when I ssh - stop being tarded?" Or ???

Folks mention "it works now" - but under zero circumstances does it work.

What am I missing?

DHowett commented 4 years ago

@lucky-wolf which version of the SSH client are you using? The one that came with Windows, 7.7, has some input bugs that result in it dropping certain keys even when “Windows Terminal” sends them.

We’ve worked it out with their team, and versions 8.1 and above should support everything the Terminal does.

If you’re using WSL and running SSH inside that, it would be very helpful if you’d file a new bug because that’s unexpected and undesirable behavior.

DHowett commented 4 years ago

Alright, now that I'm at my machine I can demonstrate this a little better. I've used the showkey utility (part of the kbd package on Ubuntu and Debian) to record the encoding for Ctrl+Backspace.

ssh under wsl

% wsl ssh -4 dustin@antares -t showkey -a

Press any keys - Ctrl-D will terminate this program

^H        8 0010 0x08
^D        4 0004 0x04
Connection to antares closed.

ssh 7.7 (win32-openssh, shipped with windows)

% ssh -V
OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5

% ssh dustin@antares -t showkey -a

Press any keys - Ctrl-D will terminate this program

^?      127 0177 0x7f
^D        4 0004 0x04
Connection to antares closed.

ssh 8.1 (win32-openssh, newer version from their repository)

% ssh8 -V
OpenSSH_for_Windows_8.1p1, LibreSSL 2.6.5

% ssh8 dustin@antares -t showkey -a

Press any keys - Ctrl-D will terminate this program

^H        8 0010 0x08
^D        4 0004 0x04
Connection to antares closed.

^H is the correct encoding, and ^? is not. Win32-OpenSSH did not, until version 8+, trust the windows console infrastructure to generate the right character encodings. It would do so itself and in so doing it got a bunch of them wrong. This was resolved by fixing PowerShell/Win32-OpenSSH#1310 in PR https://github.com/PowerShell/openssh-portable/pull/412.

lucky-wolf commented 4 years ago

Apologies. I am not 100% certain I'm in the right place? I'm on win 10, running the "Windows Terminal" app 1.1.2021.0.

I had installed that when I was trying to find a decent shell - and wanted something that could handle PS as well as WSL (which I had installed at the time). I've since removed WSL which I found cumbersome, but I've been trying to simply use this Windows Terminal as a solid remote shell interface - it seems to support bash/zsh colorizing through ssh to various linux boxes we use at work.

And for the most part, I was very happy with it - with the one exception: ctrl+backspace doesn't delete a word. Out of frustration I did a simple search on Windows Terminal and Ctrl+BS not working, and landed here with lots of folks indicating it works great.

So, is there some other windows terminal out there? Am I using Windows Terminal incorrectly (I'm starting from a power shell 5.1.18362.752. and then running ssh from there... maybe there's a better base shell to start from?)

I see that there are much later version of PS - so I'll upgrade to 7.03 now. I can reinstall WSL if that works better? I'm not very interested in PS for any local work - though I don't mind learning a bit about a new shell - but 98% of what I need is a reliable flexible terminal to ssh into various linux boxes to do basic configuration / log gathering / troubleshooting --

And not having ctrl+backspace just makes the typing much harder then it needs to be (when the rest of the terminal experience is quite excellent).

And hmm... yes - I'm running: ssh -v OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5

That looks like my other half of the problem!

Sorry for being such a noob. This looks like the help I needed, @DHowett ! Much appreciated!


Update:

I've updated to power shell 7.03 Updated to OpenSSH_for_Windows_8.1p1, LibreSSL 2.9.2 but when I ssh8 into my linux box, ctrl+bs doesn't do word-delete.

If I do the exact same thing from my Mint VM using it's native terminal and ssh implementation, ctrl+bs works.

so I guess I'm still at a loss as to how to accomplish this? :/

rkeithhill commented 4 years ago

I had to execute the following command after opening the ssh connection to get Ctrl+Backspace to work on my Linux VMs:

stty werase ^h

Note that I'm on the latest Windows Terminal Preview and OpenSSH 8.1. BTW while that works in the bash shell you ssh into, once you start up pwsh on the remote, Ctrl+Backspace is back to deleting single chars. I tried the stty command in PowerShell, no joy.

BennyAlex commented 4 years ago

@DHowett-MSFT why is this closed? It still occurs, at least in bash. In powershell and cmd it works fine for me.

mkitzan commented 4 years ago

WSL based terminals do not delete whole words with Ctrl+Backspace

WSL does not interpret the Ctrl+Backspace virtual key sequence as "delete whole word" for whatever reason (not sure about WSL2). If you open any old WSL based terminal (like the Ubuntu shell from the MS store), Ctrl+Backspace will not delete whole words for this reason. If you want to delete whole words in a WSL based terminal, Ctrl+W will do it. Ctrl+Backspace works on CMD and PS because they process the virtual key sequence as expected.

(read the thread / PR, it's all there)

Animeshz commented 3 years ago

I don't know if its related @BennyAlex @mkitzan, but Alt+Backspace seems to work perfectly fine. Is there's any plan to be able to edit the hotkeys or not 🤔?

BennyAlex commented 3 years ago

@Animeshz it works fine if your using powershell or cmd, but if your using WLS or bash it wont. In bash you have to add bind '"\C-H":backward-kill-word' to ~./bash.rc.

As you said, it wouldbe really nice to configurate this inside Terminal settings as a Hotkey/alias.

Animeshz commented 3 years ago

@BennyAlex It does, in WSL2 -> Ubuntu via the Alt+Backspace.