fish-shell icon indicating copy to clipboard operation
fish-shell copied to clipboard

Revert `alt-backspace` behaviour on non-macOS systems

Open ndrew222 opened this issue 1 month ago • 17 comments

EDIT for visibility:

alt-backspace deletes entire tokens now. Bindings for deleting words are

  • ctrl-backspace (backward-kill-word)
  • ctrl-w (backward-kill-path-component)
  • alt-b alt-d (backward-word kill-word)

See here for the full set of bindings that were changed.


As of Fish 4.1.0, the default behaviour of alt-backspace is to delete entire arguments^1

On non-macOS systems, alt-left, alt-right, alt-backspace and alt-delete no longer operate on punctuation-delimited words but on whole arguments, possibly including special characters like / and quoted spaces. On macOS, the corresponding ctrl- prefixed keys operate on whole arguments. Word operations are still available via the other respective modifier, just like in most web browsers.

I would argue that the macOS behaviour is the desired behaviour as

  1. It has been the behaviour before this change, and many users would be used to it
  2. You can still have the convenience of deleting entire arguments via use of the ctrl-backspace keybinding
  3. It is really irritating to context-switch between something that uses readline-style/Emacs-style alt-backspace and fish now. Back when the behaviour was consistent, there was no friction switching between these.

I hope that the case I have made for the reversion will be considered. I very much enjoy using fish, save for this one change.

ndrew222 avatar Nov 30 '25 09:11 ndrew222

#11518 seems relevant here. This seems like a conflict between emacs- and CUA-style bindings. I'm guessing most users (myself included) prefer the new behavior, but there should be an option to switch back (presumably by using the emacs-style bindings).

ParadaCarleton avatar Dec 01 '25 04:12 ParadaCarleton

as someone who very much prefers the emacs bindings, I would have been happy with a small note in the release notes that explained that adding this

bind alt-backspace backward-kill-word
bind ctrl-alt-h backward-kill-word
bind ctrl-backspace backward-kill-token
bind alt-delete kill-word
bind ctrl-delete kill-token

to your config file would restore the old behaviour. I had to do a bit of digging to find it. I don't particularly see the need to add a switch anywhere, complicating fish itself.

rski avatar Dec 02 '25 14:12 rski

I'm guessing most users (myself included) prefer the new behavior

I get that the new behaviour can be more convenient, and I actually was trying to get used to the new behaviour, but the annoyance really started to hit me when I started using an application that used readline for the terminal bindings.

I really don't see why the change wasn't done by making ctrl-backspace act as kill-token and preserving the alt-backspace behaviour, as it wouldn't have ruined anyone's muscle memory.

I don't particularly see the need to add a switch anywhere, complicating fish itself.

I think the option, in this case, is better; there's bound to be someone in the future who will want to use the emacs-style keybindings, especially if they got used to it from bash or emacs, or any other GNU utilities.

ndrew222 avatar Dec 02 '25 17:12 ndrew222

@rski your code block looks a bit incomplete. Since the aforementioned update, alt-left and alt-right both move by argument/token, instead of by word (as it previously was). It doesn't affect me that much, as I use alt-b and alt-f for that, but occasionally I will use alt-right and get thrown off lol.

ndrew222 avatar Dec 02 '25 17:12 ndrew222

I agree it would be good to revert this.

Due to work, I run Fish on Macs, a variety of Linux distributions, as well in a number of docker containers. This change is gonna wreak havoc on my muscle memory as versions of fish including this slowly trickle through distributions.

Due to the number of contexts I use fish in, I would really rather not have to start deviating from the default configs on the Linux side, but this might make alt+movement/backspace behave unpredictably for a few years, and I can't switch my Mac around and start using Ctrl, because older versions of Fish on Linux just do nothing with it.

Edit: Looks like that is just when SSHing to Linux through iTerm or Terminal, using Konsole on Linux, it looks like older versions do respond to Ctrl+Arrows. No Ctrl+Backspace however.

ahti avatar Dec 02 '25 21:12 ahti

I didn't even know about ctrl-backspace and was getting really frustrated with alt-backspace deleting way too much. Especially because I'm used to alt-backspace and will just do it without thinking, then I need to rewrite the entire thing again (usually a path)

I don't understand why this was done this way. Anyone who previously used the feature will be running into this issue. Good to know I can change it back to the old way, I will do that.

Xandaros avatar Dec 03 '25 20:12 Xandaros

I need to rewrite the entire thing again

No, you can use undo: ctrl-z or ctrl-/ (like in Bash).


FWIW here is the full set of bindings that was changed, if you want to flip them.

We've had a lot of reports about this^1 so we may want to do something. So there are three reasons for the old behavior:

  1. habits
  2. compatibility when switching between macOS and Linux
  3. compatibility with readline/emacs

Regarding 1, I think breaking interactive behavior is generally okay if there is a good reason (which is debatable).

Regarding 2, this seems like a relatively weak argument because people who regularly switch between those two OSs already need to put up with other key binding differences. In particular, alt-backspace does nothing on Linux web browsers, and ctrl-backspace does nothing on macOS web browsers, and I'm not sure anyone has asked about browsers to change?

Reason 3 makes sense; However I was surprised it was so significant because there are various alternatives:

  • ctrl-backspace (which matches CUA; applications should adopt the kitty keyboard protocol to be able to use it)
  • ctrl-w (note that in bash this deletes a bigword, but not in zsh or python)
  • alt-b alt-d

Good point about the conflict with CUA bindings, so if we revert this, the current platform-dependent behavior should be moved to a fish_cua_bindings (it would be easy to add those but someone needs to do it).

So I wonder if we should:

  • revert alt-$arrow and move token-movements to either ctrl-$arrow or ctrl-alt-$arrow
    • note that Vim does use ctrl-$arrow for word-movement, so maybe we'll keep that
    • ctrl-$arrow is not great because of the conflict with CUA bindings
    • ctrl-alt-$arrow is not great because it uses a lot of modifiers (esp. on a 60% keyboard where arrows need a modifier).
    • any other idea for token bindings?
  • or only change alt-backspace if it's mainly about that one (though I hear it's not, and this would be inconsistent)

Emacs isn't exactly known for having modern defaults, but I guess since fish tries to be "like bash but better", staying close to bash might be a good idea.

For users who are not already familiar with Bash/Emacs, it seems better to stay closer to CUA (note that like fish, text editors Sublime and Micro also bind the "unused" chord (ctrl-arrow/alt-arrow on macOS/non-macOS resp.) to do something else). Case in point: a lot of people are not aware that undo works in shell (see above), so fish binding it to ctrl-z presumably helps discoverability a little bit.

So it basically boils down to which user persona is more important (numerous?), someone who already knows Bash, or someone who expects OS-native bindings. I can't really tell; it seems like the latter group tends to grow in importance, but maybe the world is not ready for that switch yet. Maybe partly because Bash and some older terminals don't support ctrl-backspace yet :(

krobelus avatar Dec 04 '25 09:12 krobelus

Due to work, I run Fish on Macs, a variety of Linux distributions, as well in a number of docker containers. This change is gonna wreak havoc on my muscle memory as versions of fish including this slowly trickle through distributions.

Should be easy enough to have a separate setting to enable Mac-like key bindings.

ParadaCarleton avatar Dec 04 '25 19:12 ParadaCarleton

Hate to be the XKCD 1172 person, but the change to alt-backspace deleting the whole argument broke a lot of long flag and long args workflows for me.

At work we do work/yourname/branchname for git branches, and often I used to just do:

git sw<right> <alt-backspace>otherbranch # git switch, 8/9 key presses + branch name
# or
git br<right> <alt-backspace>newbranch # git branch, 8/9 key presses + branch name

Which lets me rely on fish's amazing tab completion to type substantially less to create and switch between branches. With the current behavior I have to either retype the entire thing or press backspace multiple times.

It also affects things like adding the --no-verify git flag from an existing history git commit message, among other examples. For example, for something like git commit --message "blep", I can do:

git com<right> <alt-left><alt-left>--no-v<tab><enter>

Sometimes you also want to just modify rather than remove one or a few flags from an existing long command and that's substantially easier if you delete only words.

In summary, the workflow of alt-backspace deleting the entire argument only works for small flags where retyping might be faster, it substantially makes things slow for long flags, especially if it's a flag in the middle of a command, unless what you want to do is to remove one full argument. In other words, it optimized for only one action (remove full argument) in detriment of other actions (remove part of argument, modify argument).

herzenschein avatar Dec 05 '25 17:12 herzenschein

Regarding 2, this seems like a relatively weak argument because people who regularly switch between those two OSs already need to put up with other key binding differences. In particular, alt-backspace does nothing on Linux web browsers, and ctrl-backspace does nothing on macOS web browsers, and I'm not sure anyone has asked about browsers to change? [...] So it basically boils down to which user persona is more important (numerous?), someone who already knows Bash, or someone who expects OS-native bindings.

We need to put up with key binding differences in the native UI of the different platforms, yes. I can't recall an instance of having any difference in key binds in any terminal UI I have encountered so far, although I'm willing to believe there might be some I am simply unaware of.

Given that experience, I think I just always viewed the shell as a completely separate environment that, luckily for someone switching between OS often, behaved the same everywhere, and I don't really see any reason why that would need to change, unless maybe it was a concerted effort across the ecosystem. I can't use Ctrl+A and Ctrl+E in my Linux web browser text fields either, yet I wouldn't want fish or bash or whatever to remove that keybind.

I think the idea of adding a separate binding set that emulates the current OS, and reverting the change for the default bindings makes a lot of sense. Note that the function description for fish_default_key_bindings says "emacs-like key binds" as well.

It might even be a sensible decision to switch the default in a major release at some point, but I don't think slowly changing around keybinds bit by bit will result in a good user experience. Giving fish the reputation of "don't bother learning keybinds because they change all the time" doesn't sound like good PR to me.

ahti avatar Dec 07 '25 18:12 ahti

If I may chime in, this is very painful change to see. Previous behavior was very useful, while I never used ALT-BCKSPC before, with fish I started enjoying it.

 bind --preset $argv alt-backspace backward-kill-word 

(thanks rski) is most reasonable default IMHO.

okias avatar Dec 13 '25 09:12 okias

This is on every platform as far as I can tell, incredibly annoying since there's no other hotkey to just delete the 1 word

is ctrl-backspace many of you mentioned mac only? Doesn't do anything on any of the 4 systems I just tried..

https://fishshell.com/docs/current/relnotes.html#new-or-improved-bindings

their hot keys are not the same as web browsers ever, nor are they now lmfao

G2G2G2G avatar Dec 15 '25 19:12 G2G2G2G

With the current behavior I have to either retype the entire thing or press backspace multiple times.

since there's no other hotkey to just delete the 1 word

There's three alternatives

ctrl-backspace (backward-kill-word)
ctrl-w (backward-kill-path-component)
alt-b alt-d (backward-word kill-word)

ctrl-backspace only works on terminals that support the kitty keyboard protocol

krobelus avatar Dec 16 '25 05:12 krobelus

It's not really about missing alternative, it's about breaking your users workflow. This is unfortunate, especially as it differs from some other widely used Linux shell defaults. Were it the case when I decided to try fish a couple of month ago, I would probably have kept using bash instead.

Deleting entire paths all of a sudden after a system update when you are used to delete only single words at a time with a given keystroke that worked for years is extremely annoying.

rbernon avatar Dec 16 '25 21:12 rbernon

Also, I should probably say that from your offered alternatives:

ctrl-backspace doesn't work on common default installed terminals (say for instance gnome-terminal), which do not support the kitty keyboard protocol. ctrl-w (backward-kill-path-component): isn't exactly the same as backward-kill-word alt-b alt-d (backward-word kill-word) is not seriously considered as an alternative to alt-backspace is it?

rbernon avatar Dec 16 '25 21:12 rbernon

as someone who very much prefers the emacs bindings, I would have been happy with a small note in the release notes that explained that adding this

 bind --preset $argv alt-backspace backward-kill-word 
 bind --preset $argv ctrl-alt-h backward-kill-word 
 bind --preset $argv ctrl-backspace backward-kill-token 
 bind --preset $argv alt-delete kill-word 
 bind --preset $argv ctrl-delete kill-token 

to your config file would restore the old behaviour. I had to do a bit of digging to find it. I don't particularly see the need to add a switch anywhere, complicating fish itself.

Sorry, maybe I'm doing something wrong, but can you spell it out the workaround for me? I can't get this old behaviour to work for me. This new behaviour is dreadful and I can't find any key combination out of the box that does the backward-kill-word.

OS: Fedora Linux 43 (KDE Plasma Desktop Edition) x86_64 Shell: fish 4.2.0 Terminal: konsole 25.12.0

Do I just append as is to the end of ~/.config/fish/config.fish?

Some suggest without the $argv, and that doesn't work either.

I restarted the machine, and it still has the new behaviour. Any suggestions?

sammyj85 avatar Dec 18 '25 02:12 sammyj85

Do I just append as is to the end of ~/.config/fish/config.fish?

yes. Lose the --preset (and the redundant $argv) then it will work

krobelus avatar Dec 18 '25 07:12 krobelus

if status is-interactive
    # Commands to run in interactive sessions can go here
end

function fish_user_key_bindings
  bind --preset $argv alt-backspace backward-kill-word
end

this also works, I guess the fish keybinds thing is old way though

G2G2G2G avatar Dec 18 '25 19:12 G2G2G2G

Do I just append as is to the end of ~/.config/fish/config.fish?

yes. Lose the --preset (and the redundant $argv) then it will work

Thanks, works great!

sammyj85 avatar Dec 19 '25 03:12 sammyj85

I hate to be that guy too, but this seriously messed me up. I thought something was wrong with WSL and spent hours debugging because of this change.

I understand the arguments, but could we please not break userspace, at least not without a big ol' warning and a way to turn it back in said warning?

cmdremily avatar Dec 22 '25 11:12 cmdremily

For breaking changes like this, a reverse-migration config should be shipped in a commented-out form. Theres no reason 5 lines of binds should be this heavily discussed (and community provided migration folded).

Thanks for the fish though...

pancsta avatar Dec 28 '25 23:12 pancsta