-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support history expansion (e.g., bash's !!, bang bang, and !$, bang dollar, tokens) #288
Comments
It is discussed in documentation FAQs : http://fishshell.com/docs/current/faq.html#faq-history |
Thanks for the clarification. I understand the rationale for removing history characters. However, while I understand the rationale for this and that it is possible to use C-e and C-a instead of End and Home, for many users, especially those used to !! and those on a laptop that do not have Home and End keys, it is still much easier to type sudo !! than Up+C-a+sudo. Would you still consider restoring functionality of history substitution tokens? |
Since it's a rare case where !! is more comfortable to use, try the following function: function sudo!!
eval sudo $history[1]
end which is called just by "sudo!!". Or the other possibility which I use: function .runsudo --description 'Run current command line as root'
commandline -C 0
commandline -i 'sudo '
commandline -f execute
end
bind \es .runsudo Then by pressing M-S I run the current command line with sudo put just in front of it. |
I made a slight variation of the last command:
It saves the cursor position instead of outright executing it. |
!$ would also be nice to have |
function sudo
if test "$argv" = !!
eval command sudo $history[1]
else
command sudo $argv
end
end
|
Thanks. There is a very sizable chunk of people who use sudo !! give that this syntax is supported across many other shells including bash and zsh. sudo !! is easier to type than using the home and end keys since those keys are farther away. I would suggest having the above function be included with fish-shell by default. |
!! is a good candidate for an abbreviation (#731) |
Expressing support for !! and related shortcuts. It doesn't hurt to add it and it feels like fish is just shoving personal philosophy at its users. |
Adding myself |
Despite it being old, it's a feature that really should come as default in Fish. There's no reason not to have it - if you don'r want to use it personally, that's fine, but having an extra command doesn't really hurt anyone - people like doing things different ways. |
The way !! is implemented in most shells does hurt people. For example, consider this command:
in bash / zsh / tcsh, this will do something unexpected and horrible, because the !! is magic syntax. This is the sort of weird interactions that fish tries very hard to avoid. My suggestion was to implement !! not as magic syntax, but as an alias. This means it would only do something special in 'command position' - it won't expand in arguments. It also keeps the feature set of fish down, which is desirable. To make that useful, we would need to teach fish about subcommands, with |
Your proposed solution falls apart when you consider |
With aliases, only commands get expanded, and fish would know which arguments are (sub)commands and which are not. So SirCmpwn is correct that requiring comprehensive function signatures is a disadvantage of the alias approach, and also that other syntactic elements are confusing. Real-life examples include the annoyance of brace expansion with git (#434) or wildcards (#967, among others). Syntax comes with a high cost, and we try to eliminate syntax when it's redundant with other features (e.g. #354). Anyways that's my argument for why supporting !! as an elementary syntactic element is a no-go. However I'm open to introducing it in ways that don't require modifying fish syntax. |
I think the comparison with |
I claim that However, |
Adding myself - just ran into this my first weekend with fish. Should definitely be supported. |
Adding myself - need this. |
For those desiring this, the function and bindings mentioned earlier in the discussion have given me an easier workflow for prepending You should give them a try. It made me go revisit my readline and zsh configs to have similar bindings. It turns seven keystrokes (two of those shifted) into a single binding. |
Regardless of what you like - is there really any reason for !! not to be supported? Everyone has different things that work for them, and though some people might enjoy using the up arrow, a lot of people enjoy using !!, and honestly, why would it be a bad thing? Those who don't want it don't have to use it. Surely it's not that hard to implement?... Yes, I know you can hack it together with fish scripting, but it does not work in the same way as in bash or similar shells, which was quite convenient a lot of the time. |
See my comment above for my rationale for why I don't want to introduce this the way that bash and zsh do it (as a new syntactic element), and my proposal for a way it could be done that keeps with the fish philosophy. |
The argument of "echo fish is great!!" being better than using '!!' for history is a bit weak, but I understand the point. Seems like a simple "set shell_history advanced" or something could allow it for people willing to risk "echo fish is great!!" getting an error message. Nevertheless, my use case of '!!' is similar but could be avoided with some feature enhancement perhaps. For example on my mac with bash: So I somewhat regularly use the output of the previous command for a new command. Unfortunately even though fish is fairly proud of using () for sub-commands instead of "confusing" backticks and such, it doesn't really treat them as such until you hit enter. At least that is what I see. If fish would allow a history search after the first '(' (aka a subcommand) I think it would be easier to handle not having ! history manipulation. |
If I understand the suggestion, it's that when you press up arrow, it should perform history replacement only within the innermost subcommand instead of the entire command line. |
👎 I still support simply implementing bash-style |
I'd prefer :up_arrow:, Ctrl+p and command history search working in subcommand positions over introducing !! The entire history API of other shells is confusing enough that people usually only remember !! from it. |
Correct. That would be convenient and fairly easily replace the '!!' Or !keyword use. |
@tukusejssirs and @ClickSentinel, have you tried adding the code at #288 (comment) to your config? I've had a variant of that for several years (modified from an issue (this issue, maybe?) in my config, and it's one of the pieces of shell ergonomics I rely the most on. (Also, especially with the additional case I have in my variant to do an upward token search using the string prior to the My variant (or maybe I stole the variation...can't remember 🤷♂️ ): function bind_bang
switch (commandline --current-token)[-1]
case "!"
# Without the `--`, the functionality can break when completing
# flags used in the history (since, in certain edge cases
# `commandline` will assume that *it* should try to interpret
# the flag)
commandline --current-token -- $history[1]
commandline --function repaint
case "*"
commandline --insert !
end
end
function bind_dollar
switch (commandline --current-token)[-1]
# This case lets us still type a literal `!$` if we need to (by
# typing `!\$`). Probably overkill.
case "*!\\"
# Without the `--`, the functionality can break when completing
# flags used in the history (since, in certain edge cases
# `commandline` will assume that *it* should try to interpret
# the flag)
commandline --current-token -- (echo -ns (commandline --current-token)[-1] | head -c '-1')
commandline --insert '$'
case "!"
commandline --current-token ""
commandline --function history-token-search-backward
# Main difference from referenced version is this `*!` case
# =========================================================
#
# If the `!$` is preceded by any text, search backward for tokens
# that contain that text as a substring. E.g., if we'd previously
# run
#
# git checkout -b a_feature_branch
# git checkout master
#
# then the `fea!$` in the following would be replaced with
# `a_feature_branch`
#
# git branch -d fea!$
#
# and our command line would look like
#
# git branch -d a_feature_branch
#
case "*!"
# Without the `--`, the functionality can break when completing
# flags used in the history (since, in certain edge cases
# `commandline` will assume that *it* should try to interpret
# the flag)
commandline --current-token -- (echo -ns (commandline --current-token)[-1] | head -c '-1')
commandline --function history-token-search-backward
case "*"
commandline --insert '$'
end
end
function fish_user_key_bindings
bind ! bind_bang
bind '$' bind_dollar
end |
Thanks @scooter-dangle this works even better than #228 |
There are cases where Fish will provide more idiomatic way to do some action:
Maybe However the proposal should be just as efficient. Compare:
For |
I think it was a mistake to mark this as a duplicate and lock conversation: the mega-super-duper abbreviation plans don't obviate this issue. Abbreviations will be the mechanism used to implement history expansion but the way this was triaged suggests fish-shell developers specifically decided not to ship the feature or plan on the story being "users should implement it themselves". We can expect a separate PR implementing history expansion after the new |
Is the proposal to add a default abbreviation for |
from the PR
After the enhanced |
Right on. When that lands, I look forward to configuring without |
Shouldn't this issue be closed as resolved, since PR #9313 has been merged into master and fish 3.6.1 (containing the changes) has been released? Thanks to bringing this feature into Fish, BTW! 🥳 |
Yeah I'm closing this in favor of #9462 - it's possible to add this now, so the question is if we want it by default. This issue is massive, so it helps to have something a bit more focused. |
It appears that the double-bang does not work and is somehow interpreted as a program which sudo unsuccessfully tries to locate. This occurs on Ubuntu 12.04 LTS with fish-shell compiled from source.
Steps to repro:
Execute any command:
$ ls
Execute the previous command as root:
$ sudo !!
sudo: !!: command not found
Expected behavior:
Command
sudo !!
executes previously executed command (ls
) as root.I also checked that the issue isn't caused by
sudo
by following repro steps in bash, which behaved as expected.Also, note that an earlier version of fish-shell on Mac OS X 10.7 did not have this problem and
sudo !!
worked as expected.The text was updated successfully, but these errors were encountered: