Hacker News new | past | comments | ask | show | jobs | submit login
New Features in the Fish Shell (lwn.net)
316 points by chmaynard on Sept 29, 2020 | hide | past | favorite | 138 comments



As a long-time power user of fish for 6+ years, I cannot live without it. It's easily in my top 5 most game-changing upgrades to my dev environment. (up there with a clipboard history manager and TabNine for code autocompletion)

Over the years I've amassed hundreds of fish functions for common tasks on my machines, https://github.com/pirate/fish-functions. I loved it so much I started using it to write devops/deployment scripts instead of bash. That was a mistake.

It has some serious limitations as a scripting language, namely lack of proper subshell support and background process control. The relevant issues have been open for years with no clear resolution in sight. (which is fair, these are very hard problems and it's an open-source project with finite resources)

That's fine though, it's still my favorite interactive shell for use in a Terminal. I just make sure to write any script longer than a few lines in Bash. https://github.com/pirate/bash-utils


The best part about fish is you don't have to configure it much to be productive in it. It is really nice that the fish maintainers think hard about what should be configurable, and what sane defaults should be. This is not as common as it should be in OSS. Contrast with zsh, which has a billion knobs to tweak, and the consensus is that everyone should install a huge "community dotfile framework" (whatever that means) consisting of tons of opaque aliases and settings, some of which might make your shell startup lag.

More to a specific point: I haven't had much of an issue with fish's subshell/backgrounding control. That doesn't mean that there aren't issues, just that my interactive use doesn't trip into them.

I will note that you can write an async git prompt using nothing but fish itself, which I consider an advanced use case for a shell. Check it out:

https://github.com/mattgreen/lucid.fish


I ended up implementing my own background process management for fish here, it uses bash to fork a subshell with fish inside of it, which seems to solve all the problems I encountered.

https://github.com/pirate/fish-functions/blob/master/backgro...

https://github.com/pirate/fish-functions/blob/master/progres...

https://github.com/pirate/fish-functions/blob/master/signal....

https://github.com/pirate/fish-functions/blob/master/fork

Usage:

    background progress_await compiling_task_finished

    g++ ... some slow command

    signal compiling_task_finished
This allows the progress bar to truly run at the same time as the g++ command and receive a signal from the fg process when it's time to complete, something a simple & does not let you do in fish.

I've collected more details on Fish's issues here for anyone interested:

https://github.com/pirate/fish-functions#issues-with-fish


I like your semaphore idea a lot! Might be a good primitive to put in fish.


Very true. I have been using fish for the last five years without really learning the shell. The auto-complete itself feels so good and makes me productive.

Confession: I haven't taken pains to learn any shell after that. Almost similar to why I never took to try out VSCode after getting used to Sublime Text. So many demos, videos etc. quite tempt me to try out VSCode but still haven't ever got to it)

The only thing that I took note was to install https://github.com/oh-my-fish/oh-my-fish every time I setup a machine.

Would be great to know of any quick to learn fish-hacks or fish-for-dummies resources


Most common bash/zsh syntax works in shell. For most day to day shell usage, I'd say:

* get comfortable with stdin/stdout/stderr syntax (and redirection)

* get piping down pat. It's so useful.

* practice using &&, ||, and ; to sequence commands

* know how to use ENV=value to override env vars, and understand how env vars work

* yak shave a bit and make some aliases/functions in your shell based on your usage patterns

From here, it gets esoteric pretty fast, no matter what shell you're in. But you have enough concepts to figure out you need from there.


As for zsh, I partially agree, but you don't need to go with something heavy like oh-my-zsh. I use prezto, and it's great.


and if you need to configure something, it actually has a really pleasant ui that can be called with `fish_config`.


Fish functions are just gorgeous, and what made me drop Zsh like a hot potato. Suppose you want to make an automatically loaded (that is, not defined in the shell's rc file) function called foo. Here's how you do it:

- Make a file named ~/.config/fish/functions/foo.fish

- Inside it, define a function named "foo"

That's it. Now when you open a new shell and try to run the command "foo", Fish will look for the file named foo.fish in that directory, load and execute it, then call the foo function from in it.

Now, create an autoloaded function in Zsh or Bash without looking at a man page.

There are a million little niceties like that where I'd assumed that a certain task had to be complicated because every shell I'd used before had made it complicated, but then Fish came up with a nice convention for making it simple. Want to make a function to dynamically set your shell's prompt? Create a function named "fish_prompt" in the file ~/.config/fish/functions/fish_prompt.fish. Ta-da - turns out it doesn't have to be a pain in the neck to do that.

I completely agree about using it as a scripting language, though. It's great for making functions for your interactive shell, but stick with sh or bash (or Python) for writing more sophisticated stuff.


> Now, create an autoloaded function in Zsh or Bash without looking at a man page.

For zsh:

- Make a file named ~/.config/zsh/functions/foo

- Inside it, define the body of the function for foo

- Add ~/.config/zsh/functions/foo to $fpath with "fpath+=~/.config/zsh/functions"

- Declare foo with "autoload -Uz foo"

> Want to make a function to dynamically set your shell's prompt? Create a function named "fish_prompt" in the file ~/.config/fish/functions/fish_prompt.fish. Ta-da - turns out it doesn't have to be a pain in the neck to do that.

To do the same in zsh:

- define a function (can be autoloaded or not) named prompt_foo_setup to change your prompt

- add the following to your zshrc: "autoload -Uz promptinit; promptinit"

Now you can easily change to your custom "foo" prompt by running "prompt foo".

There are many valid points which make zsh (or bash) hard to use out of the box, but neither of the points you've raised are one of them. One can easily do both without "looking at the man page."


That's what I'm talking about. I'm super comfortable reading the man pages for things, but if a tool wants to take over all the boilerplate and do things for me, awesome! Sure, I can add a function by editing rc files. That doesn't scare me one bit. But... why? There's a lot to be said for convention over configuration.

For context, for a while I was the FreeBSD port maintainer for shells/bash-completion. I'm (too) familiar with the plumbing of various shells. I can do all the manual work myself, but there are lots of things I'd rather be doing instead.


> One can easily do both without "looking at the man page."

How do you know which flags to autoload to use without reading the docs? How did you know to call autoload?


Oh please. The exact same thing can be said for fish. How did the parent commenter know to create a file named ~/.config/fish/functions/foo.fish? How did the parent commenter know to define a function inside that file?

The point is, it's trivial to create an autoloaded function in both fish and zsh. You don't have to look at the man page each time, which is what was being implied in the comment I was responding to.

But to answer your question, you never need to call autoload with flags other than "-Uz" 99.99% of the time. So the idea that you have to consult the manual each time to figure out the flags is plainly not true. As for the fact that you have to call autoload to bring autoloaded functions into scope, what else did you expect? Fish's behavior of bringing undeclared functions into scope isn't exactly intuitive either.


Or even more simplified:

    funced foo
    funcsave foo
funced will either allow you to edit it inline, with a clever multiline system, or through your $EDITOR.

funcsave will record the file to the place you want once you're happy with the changes.

Which means you can funced as many times as you want on both new and old alike until you're happy with the function.


Or even easier:

    funced foo
Then edit your function in the editor, save and close it, and then:

    funcsave foo
to make sure it's there in the future sessions. Without that second step you can create one-time helper functions for the active session.


  for fname in $(ls ~/.config/zsh/functions); do source $fname; done
:)


That’s the exact opposite. That’s eagerly loading all defined functions. autoloading means the function isn’t loaded until it’s used.


When are you going to run that?

GP is talking about JIT loaded functions: 'that is, not defined in your shell's rc file'.


for fname in ~/.config/zsh/functions/*; do source $fname; done

will prevent issues with special chars and spaces in filenames


I've been using fish for longer than I can remember, but I almost never write fish functions. The out of the box experience is already much better than bash/zsh (out of the box, not including plugins/etc).

I also prefer the basic syntax for things like for and while looks on the command line, the way they get formatted. With bash I always had to look up the syntax because I didn't use it much. Fish, I barely have to look up things because they are pretty intuitive, for the most part.

Also, no adding `export X=Y` to your .bashrc because you can just `set -U` and it automatically saves it between sessions.


> It has some serious limitations as a scripting language, namely lack of proper subshell support and background process control. The relevant issues have been open for years with no clear resolution in sight. (which is fair, these are very hard problems and it's an open-source project with finite resources)

You say that but I'd been writing a shell in my spare time and I solved those problems over the course of a few weeks. For me though, they were important problems to solve because few other lesser mainstream / alternative shells addressed those problems and thus they became all the more tantalising problems to solve. In Fish's case, they might be lower priority jobs.

Unfortunately though, I also broke job control support again earlier this year and haven't had the spare time during the pandemic (my kids have been understandably more demanding of my time now that I'm working from home) to fix it. So I can't demo that particular feature as working. As an aside, this is also a good lesson to everyone to write robust tests....


In particular I think Fish struggles with backgrounding of functions (backgrounding of non-fish commands seems to work fine).

  # these behave the same in bash but differently in fish
  some_command &  # this works
  some_function & # this does not
The relevant issues are listed here if you're curious about why it's difficult to implement this in Fish: https://github.com/pirate/fish-functions#issues-with-fish


Thanks for the link. Makes sense that if Fish doesn't fork itself and isn't multi-threaded then that would be a difficult feature to implement. I had the same consideration right at the conception of my project: fork or multi-thread? I went with the latter. But my shell diverges quite a bit from the typical design a shell would take so there's a lot of reasons it's sub-optimal compared to the excellent work the Fish guys have done with their shell.


This is off topic, but I'm curious about your top 5 most game-changing upgrades to your dev environment.

Just set up TabNine, what are the other 3?


Clipboard history manager (I use Alfred's on macOS), TabNine, Fish Shell, ripgrep/ag, and SublimeText's jump to definition & "show usages" for all symbols in the current project.


I will add fzf with the fish plug in, entr, z...


I personally use autojump but fzf is excellent as well.


I've a similar collection of "functions", but I implemented them just as plain bash/sh scripts in my ~/bin. I think putting your functions into regular executables on the path would have been more portable. That way you wouldn't need to call them from a fish shell to run them (you can still use fish scripting language if you like).


Agreed, I've been gradually migrating all the big ones to https://github.com/pirate/bash-utils for the past few years.


The lack of associative arrays is what does it for me.


what are the most used functions in fish? i'm quite new, i find `z` very useful to move in folders


To preface — I love Fish — "Finally, a command line shell for the 90s" is an apt description. I use it every day.

But I haven't managed to recommend it to beginners. There are so many bash instructions out there, and translating between bash and fish isn't easy for a beginner.

That's a great shame and missed opportunity, because beginners would in particular value a nice shell. The shell is often one of the harder tools to learn — e.g. I find beginners are more comfortable in a Jupyter Notebook than they are the shell.

I'm not sure whether there's a way of combining fish's ease of use with a notion of compatibility — maybe a "bash mode" for beginners, which accepts bash commands? Or error messages which return translated commands?

(I recognize not all commands can be translated, but all of those that would be run by a beginner can be)


This is the point of Oil -- having a smooth upgrade from bash. The interactive shell ended up being more work than I anticipated. So I'm looking for people who want to run with it either as a separate project or part of Oil.

http://www.oilshell.org/blog/2020/02/recap.html#fish-oil-is-...

Another option is to link Oil as a C++ library into another shell, which is starting to become possible. Oil handles all the difficult language and compatibility issues, and encapsulates them, so it's a great complement to someone who only wants to work on the interactive shell.

Even though it cleans up many legacy warts, Oil runs thousands of lines of real bash programs: https://github.com/oilshell/oil/wiki/Shell-Programs-That-Run...

Posts on the interactive shell: https://www.oilshell.org/blog/tags.html?tag=interactive-shel...


It's a chronic problem on work projects that people write shell scripts without a shebang operator at the top. Obscure error messages are usually how I find out someone is using zsh, fish, or some other shell.

I fix what I can, but it's like mopping up water during a rainstorm. Yes it's better than doing nothing, but also there will be more in twenty minutes so don't make any plans.


One way I force people (mostly myself) to include shebang lines:

Have a scripts directory in my repo that mixes shell and python scripts with no file extensions and executable bits set. If I don't put a shebang, it just doesn't run.

Of course, this requires you to have firm control of code style policies.


Make a post-commit hook that adds "#!/usr/bin/yes No." at the top of every file missing a shebang.


Heh.


But, does shebang works when you want to source some files?


you can source a file that contains a shebang in most (all?) shells assuming it contains code written in the same shell language. I.e. a bash file can't source a fish file and vice-versa.


Don’t cross the streams.

It would be bad.


Just enter "bash" when you need bash and exit it once you're done. Barely need this but sometimes it's useful.

Fish imho offers superb usability, wouldn't want to miss it.


You lose all the fish goodies when you do this, no?


you only need to paste a line or two of bash. it's what I did when I have a problem with some online help that put a line that only works on bash


Some commands are compatible with bash, but not compatible with zsh. I do the same thing when using zsh.


exactly.


I wish someone had recommended fish to me as a beginner. When I discovered it I was finally able to write some aliases and scripts without copy/pasting, overdoing it by resorting to a real programming language, or wasting an entire day trying then giving up. Concerning bash instructions, it's not that hard to translate them imo, or you can just use bass or just pop into bash for a second.


> Or error messages which return translated commands?

Fish does this in some cases:

  ~> echo $(true)
  fish: $(...) is not supported. In fish, please use '(true)'.
  echo $(true)
       ^
> (I recognize not all commands can be translated, but all of those that would be run by a beginner can be)

Not all of them, unfortunately.

Consider `while true; do something; done`. Fish interprets this as an unclosed while loop, where `do` and `done` are ordinary commands. So if you enter it you don't get a syntax error, fish just waits for more input until you enter `end`. The same goes for `if` and `for`.


Good point on the loop, I hadn't thought about that, thanks for correcting me.

On the error messages, I was thinking even clearer for beginners, giving them the whole statement, to avoid uncertainties around where the quotes should be included in '(true)'. Maybe even a shortcut to paste the corrected line in their terminal.

  echo $(true)
       ^
  fish: $(...) is not supported. In fish, please use '(true)', like:

  echo (true)

  Alt+r will insert this line in your terminal.


Actually it is more "Finally, a command line shell for the 80s".

"Xerox Alto"

https://www.computerhistory.org/revolution/input-output/14/3...

Having grown through the UNIX adoption in the enterprise, it kind of feels ironic that nowadays bash is kind of seen as the UNIX shell, and in those days it was just one among many possibilities to configure on /etc/passwd


Bash is definitely seen as the "Linux shell", but most users of non-Linux Unixes and Unix-likes don't use Bash. macOS, for instance, now uses Zsh out of the box (although most Bash one-liners still run unmodified in Zsh).

But Linux is the majority of the Unix-like market, so it (and therefore Bash) dominates.


macOS just recently switched to zsh as the default and doesn't change the shell for existing users so I imagine it is likely the majority of macOS users are still using bash.


True, although it gives you a pretty prominent notice that Zsh is now the preferred shell when you start Terminal for the first time after updating to Catalina.


I think it's referencing the color support that didn't really hit until the 90s.



Oil is more focused on making shell scripting nicer, Fish is more focused on making shell interaction nicer. Both are cool projects, just slightly different focus.


If Oil makes error checking and error messages nicer, it will have provided an awesome service to the community.


Usually, those commands can be run in bash from fish with a bash -c, or from a file.


Or via Bass[1], for things that modify the environment.

[1] https://github.com/edc/bass


Extra compatibility has been added lately, like && and ||. More bash syntax Just Works now.

I think it's fair to say "If it doesn't work in fish, just type `bash` to enter a bash shell and try again."


I don’t think this is such a big deal. Every programmer needs to become sufficient in bash because odds are you’re going to log into another computer which only has bash or csh, and likely you need to modify someone’s bash script. It’s probably best for beginners to learn bash first, and for intermediate users to switch to fish once they understand the concepts.


It actually doesn't come up that often. A lot of times you can just either A) paste one line at a time or B) use double quotes.

But what I do is I run fish manually on top of bash. If I have an issue, I just type exit and then try to paste the commands in again. Then when I am done I restart fish.


I found that adding the "&&" operator recently has fixed that for a lot of common cases. I still prefer the "; and" syntax though.


Fun story. Couple of years ago, a few colleague's and I were casually chatting at our desk about fish shell. When suddenly we hear someone a few desk away saying with a big smile: I wrote that!

We were sitting next to Axel...


Many of the comments in this thread refer to the sheer inertia of millions of LOC of bash script in the wild. This seems to be the main reason why Oil shell[1] aims to be "an upgrade path from bash to a better language and runtime".[2]

I wish them luck.

[1] https://www.oilshell.org/

[2] https://www.oilshell.org/why.html


Thanks, that is indeed the purpose of Oil, and I also noticed so many comments here pointing out the compatibility issue.

That is nearly "done" for Oil, as it runs thousands of lines of real bash scripts.

There's a big list of known and mostly trivial differences here: https://www.oilshell.org/release/0.8.1/doc/known-differences...

If you're a bash user and you want your scripts to run under Oil, I recommend testing it! If your script doesn't run, you'll probably get a better error message than bash gives you.

Or you might motivate a change the OSH language (a cleaned-up bash). It's easier to change now than later.

I'm still looking for help too:

http://www.oilshell.org/blog/2019/12/09.html#help-wanted

https://github.com/oilshell/oil/issues?q=is%3Aissue+is%3Aope...

https://github.com/oilshell/oil/issues?q=is%3Aissue+is%3Aope...


This, especially the long-awaited introduction of logical operators (&&, ||) is most welcome.

In the past I used bash then zsh then migrated to fish and not looking back. If you work in a shell a lot I can't recommend it enough; it will boost your productivity. Especially with tons of cool extras like oh-my-fish.

Huge thanks to all the contributors; keep up the good work!


I tried to use fish for a while and ended up giving up and going back to bash, mostly for one (somewhat irrational) reason: fish kept recognizing bash-isms and yelling at me about it.

Clearly there's a code path to recognize the thing, so why not just do it? It already knows what I want, why post a message instead? Either interpret it, or don't.


I get the sentiment, but not sure I agree with the "either interpret it, or don't" part - it sounds like you are essentially saying the scripting should either match Bash completely (and thus lose out on the more modern syntax) or not offer any kind of helpful error to users. Or perhaps support both types of syntax?

Personally I think it's fine to help guide new users to the new syntax without directly supporting it - this keeps Fish scripts from all devolving into the (subjectively ugly) bash format. It's like a graceful deprecation warning.

Edit: although I do think ceding on the logical operators (&&, ||) was a good move since that one is so fundamental


In the latest major version they've actually changed most of these so it's worth another try if you're so inclined.


They try to point you in the right direction but aren’t making assumptions that it’s right.

What happens if you loose data because of a wrong assumption?


I've been using fish for a long time from the 1.x branch, after a long time using bash, and tcsh before that in the 90's. Before that the primitive CMD and DOS.

I like much of what the new crew (who took it over) have done, but after installing it on a new machine recently I realized I didn't like their web configuration and some defaults. Which I almost never use, but a newbie would.

First, terminals have much improved in the last three decades. There's no obvious reason a curses-like app couldn't take the place of the web app. Configuring the shell from the web is rather gratuitous and weird IMHO.

A second, minor concern is the use of blue hues in their syntax highlighting defaults. Blue on black is rather unreadable, hard to see on its own, weakest of the colors due to eye sensitivity. It's also bad at night-time. I'd like to see a more neutral/warmer color palette for the default.

I have other nitpicks, such as their docs are not good enough on how all the types of variables work, and why you pick one or the other, for example. They moved away from the daemon, and variables no longer get propagated across shells. That was a neat feature but they removed it around the time they instituted the web server. I don't really get those design choices, but there's still no friendlier shell.


fish-shell dev here. Sounds like you have been using it longer than me!

We'd love to do a curses version of fish_config. I think you're right the default colors could be warmer and still work on light backgrounds (terminals don't publish their colors so the defaults have to work on light and dark).

Variables are still instantly propagated, it just uses fifos instead of a daemon!


> (terminals don't publish their colors so the defaults have to work on light and dark)

Hi. There are actually some possibilities there, but it is not entirely reliable. Examples are xterm sequences and the COLORFGBG environment variable. Some terminals can be assumed to be dark such as the linux/bsd console or now vintage hardware.

Windows is most often dark, but there is an API to ask as well. However, I don't think fish works there. Perhaps from LSW.

Sounds like having default colors closer to medium gray is easier.


   The web configuration bring in a hell lot of dependencies. Please make it a separate project. 
    Also if the readline part can be extracted to a separate executable, then it will be amazing. Imagine a fish like completion with psql.


The only dependency the web configuration tool should bring in is Python, which is already an optional dependency for the manual page completion generator. You can install and run fish without ever running the web configuration.


> They moved away from the daemon, and variables no longer get propagated across shells.

Universal variable changes should be propagated across different fish processes. However, it looks like the maintainers are questioning whether they should live on.


I had just tried it and it didn't work. But looking at the help, it needs a -U not a -u, thanks.


Many years ago, before I discovered fish, I tried the loved by many zsh shell, but found myself spending too much time messing with the configs to get it how i wanted. On my quest to find something better and avoid coding my own, I discovered fish. fish is easily one of my all time favorite linux cheats to increase productivity, without spending hours tweaking configs. It is very usable out of the box, and includes a web-ui mode to make easy basic customization stuff like theme and PS1 var. Finding/re-using command history is a breeze, you can

  history -c curl # Return history that contains (-c) the word 'curl'
It's one of the first pieces of software I install to new Linux desktops. I still prefer to keep my servers bare, thus I use the default bash shell there.


I've used fish in the past but went back to zsh. IIRC fish broke a bunch of times between versions and the maintainer feedback wasn't great. The maintainers of course don't owe me any of their time, so I'm not mad about it, I just don't use it anymore because I need my shell to work reliably every time I open a terminal. (I don't remember the precise problem but I'm sure I could go find it.)

I now use zsh with zgen and a smattering of modules. It works fine, doesn't have the issue that you have to first translate every snippet you find to your new shell, and it's still easy for the newer shell users in your life to use.


For anyone who needs to/prefers to use bash:

> One nice feature for fish history is the ability to filter through the history based on what is typed into the shell.

Add this to your .inputrc

  ## arrow up
  "\e[A":history-search-backward
  ## arrow down
  "\e[B":history-search-forward

> Fish does not enter any command that begins with a space into its history file, essentially treating it like an incognito command.

Add "HISTCONTROL=ignorespace" to your .bashrc

> A new addition in fish 3.0 is the --private flag that can be used to start fish in private mode; it stops all subsequent commands from being logged in the history file.

run unset HISTFILE


The inputrc change is nice, but not quite the same as what fish does.

If I type a part of a previous command in and then press the up arrow in fish it will only cycle through history records that contain that as a substring (which is really the killer part of the feature).

(Yes I know you can do similar things in bash but you have to press other keys to put it in the history search mode)


I agree, although otoh, the inputrc change is not specific to bash. It is useful for any cli that uses readline (mysql, python prompt, pgcli,...). Other useful inputrc settings I have in mine :

# - when performing completion in the middle of a word, do not insert characters # from the completion that match characters after point in the word being # completed

  set skip-completed-text on
# - displays possible completions using different colors according to file type.

  set colored-stats on
# - show completed prefix in a different color

  set colored-completion-prefix on
# - jump temporarily to matching open parenthesis

  set blink-matching-paren on

  set expand-tilde on
  set history-size -1
  set history-preserve-point on


One of the things that really bug me out about fish shell is how it completes history. If you type the beginning of a command, you can use the arrows to cycle through all matching history items. All items BUT THE LAST ONE. That one you have to complete with ctrl-f.

And the worst thing is, this behavior is completely intentionally [0]. For some time I used a patched version of fish, but it was just too inconvenient and I went back to zsh.

[0] https://github.com/fish-shell/fish-shell/issues/405


I gave fish a serious try last year, and really loved the command-line completion, but the vi mode editing was a deal-breaker. It's minimally usable, in particular it doesn't support command combinations like dt/ ct/ ; d0 etc... In the end I found a history completion plugin for zsh that worked as well as fish, and ended up going back to zsh.

The vi mode issue seems pretty hard to resolve, like have to completely reimplement the editing hard. You can, as an alternative, drop to a real editor if you need a real editor for the command. Here's the issue related to it: https://github.com/fish-shell/fish-shell/issues/4019

It's very interesting, but I'm pretty dead set on vi history editing, so it wasn't for me.

(Edit to update the commands it has issues with)


To reprise a previous comment, I think vi mode suffers because it's a relatively niche feature - none of the current committers use it as far as I know, and pull requests to improve it are relatively infrequent. 1.8% of the pull requests into the (not yet released) 3.2.0 are for Vi mode, which is a slight increase on previous milestones, and includes support for dh, dl, c0, cf, ct, cF, cT, ch, cl, y0, tilde, ci', ci", yi', yi", di' and di".

I don't think it helps that it's this huge target area which (the small number of?) users use a slightly different 10% of, and it can be quite complex to integrate new features into existing editor state.


Sure, understandable and reasonable. Just wanted to mention it for others that may care. Fish has some great stuff in there. But, in my case, 30 years of vi muscle memory was hard to blunt.


I just tried dw, cw, f/, and df/, and they all worked just fine.


I was misremembering, it was the combination with motion commands: dt/ ct/ ; d0 -- if these work now you probably want to provide feedback on the issue I mentioned above, because it's still marked as open.


dt/ cw and d0 work, but ct/ doesn't. Seems like maybe they've hardcoded certain command-motion combinations, but not actually done it "properly." FWIW, it acts enough like vi that I never noticed until today.


Fish shell is simple great. I use it for many years on my daily development on Linux/Mac without regret it. The way how it speeds up my software development process from the command line is invaluable. However I still use Bash for writing production scripts on my servers for different reasons like compatibility, requirements, etc. But when I get my server via SSH, Fish rocks also there.


happy user of fish with very few simple customizations:

    set fish_greeting
    
    function fish_prompt
      echo (set_color green)(prompt_pwd)(set_color normal)'> '
    end
edit: also there is a change that didn't get mentioned: fish now accepts `A=1 echo $A` for instance without using `env A=1 echo $A` like at some point


Holy smokes! I've gotten used to the `env` prefix but this is what kept going wrong for me. Thanks for the tip!


>not wanting to see fish being friendly every launch

The only thing I leave the default banner on is fish.


"Finally, a command line shell for the 90s"

I laughed so hard when I read their motto some years ago that I had to try it. I use it mainly for the nice autocomplete and write scripts in bash ...

It is nice that they added "&&" for "and" etc. It was quite annoying until I got used to it.


I think Fish is fantastic, but just can't use it because so many things rely on either Bash or Zsh. I've settled for a modest ZSH setup with Prezto and I'm pretty happy.


In my years as a dev I haven't found many true dependencies on Bash/Zsh. For Ruby, rbenv and other solutions worked. For Python, there was virtualfish to make virtualenvs work properly. Although now pyenv works out of the box with Fish. Other than that, simply adding a shebang to scripts is sufficient.

That being said, I don't go and convert the shell of all my AWS instances to Fish. I just keep my local shell as Fish.


I've been using fish for years now and cannot remember the last time something broke because it required bash but was run by fish.

One thing I do differently than most is I don't make fish my system-wide default shell. I leave that as whatever the system default is. Instead I just make fish the default shell within the terminal emulator I use.

Never had an issue with it, and it is much easier to setup as well.


Yeah, I think people miss that you don't have to `chsh` your shell. Perfectly fine to make your terminal launch `fish` instead of the default shell.


Pretty easy to drop into bash for a second to copy paste something from the internet and introduce God-knows-what onto your system. ;)

You can also set Fish to start up after bashrc (or whatever), so that you don't have to translate all your startup stuff.


I love fish, and use it for almost everything.

The one thing I haven't been able to get it to do is to define and export environment variables properly..

So I typically open the terminal in Bash, do whatever sourcing bash scripts that set up environment variables, or do something like that by hand, then run fish.

Kudos to the developers for building a great productivity tool. No tool is perfect, fish has its warts but it's made me much more productive.


I run it similarly.

A lot of tools add bits to .profile/.bashrc/.bash_profile so this allows inheriting that.

I use tmux and if has an option for setting the default shell and that’s where I set it.

Open terminal, loads bash with it’s environments, then tmux loads fish.


This is a great idea, and one that I think would fit my workflow very well!

I've tried fish in the past and loved it, but moved back to zsh when I realized that writing my personal scripts in fish essentially meant that I wasn't able to share them with colleagues.


Fish 3 was released almost two years ago in December 2018. It's a little weird seeing these features being referred to as "new"!


Fish 3.1.0 was February 2020, however, and includes quite a few features over Fish 3.0.0, like no longer needing `env` to set one-off variables.


I've been almost exclusively using Fish on all my installations for a few years now.

Every once in a while I have to sub to Bash, but it's very rare.


I've been using fish as my default shell for ~3 years now. The faint gray history auto-complete / search that appears when typing commands alone is a killer feature. urxvt + fish + ranger + sauce code pro font = me loving my terminal experience a ton. Thanks fish devs!


If anyone here is a zsh user and interested to use the same feature: https://github.com/zsh-users/zsh-autosuggestions It really was a game changer for me as well.


For somebody who hasn’t tried it, what are the advantages over something like Oh My Zsh?


I find it has two advantages. One, being quite a sophisticated auto-complete system. I haven't seen anything nearly as polished. The other advantage is it's easy to learn and configure. You can read the short manual and you'll know about every feature and keyboard shortcut that exists.


Fish autocomplete seemed like magic when I first started using it. I does things like autocomplete file paths on the android side of adb sync commands, autocomplete on docker container hashes..


I am a longtime zsh user and tried fish earnestly for a month or so, but gave up because I could not figure out how to ignore certain patterns while auto-completing filenames. For example, I typically edit tex files and I don't want any of the temp files to be suggested as autocomplete suggestions. In zsh, I can write

zstyle ':completion:::(vim|nvim)::files' ignored-patterns '*.(aux|dvi|log|thm|idx|pdf|rel|out|tuo|tui|tuc|tmp|mpo|mpb|mpd|1|keep|pgf|fls|gz|fdb_latexmk)'

(yes, tex generates so many temp files!) I couldn't figure out how to do something similar in fish


It’s a sane scripting language. It encouraged me to automate simple tasks, create handy functions etc. I don’t have to google the for loop syntax every time I need it.


One thing I like about Fish is that it works great out of the box, without needing to install plugins.


it's super fast (autocomplete, arrow up/down) and "looks cool" without any extra configuration.


oh-my-zsh can be quite slow on very powerful machines for very simple tasks. Also having a shell default to most of the features you need makes docs simple compared to the million flags of zsh


Oh my zsh always seemed to add several seconds to shell startup. Fish starts up instantly


I remember not switching over due to having spent years incrementally building up a bashrc. Is there a way to port it over?


I've made use of 'bass' before. The example they have is sourcing nvm's bash script so it's usable in fish. https://github.com/edc/bass


What I do is run bash as default and then fish on top of it


Oh, that abbreviation feature looks useful.

Combine it with that idea of "prefix your local scripts with a comma" and it seems a neat way to save typing.


Fish's plugin ecosystem looks much smaller than that of zsh's. Is there some plugin or feature of zsh that fish does not have?


It also has a lot built in.

Anything you use on ZSH that you’re not seeing?


I gave it a try a while back but it apparently needs IPv6 to be enabled to use its web interface. Is this still the case?


It has a web interface as well?


thanks fish contributors. just upgraded and even simple ls -la is snapper. so excited to have normal environment variable usage


Fish Shell has a lot of cool feature but lack of `ctrl-r` functionality is preventing me from using it full time.


You can just type in anything you'd like as when using Ctrl+R and then just press the up arrow key to perform a fuzzy match in your history.


Does fish have its own inputrc ?

I'm sure it uses inputrc or similar, giving you a thing like:

  $if mode=emacs
  "\e[A": history-search-backward
  "\e[B": history-search-forward
  $endif
aka, type "fish" and press up arrow to only go through history that starts with "fish"

also, how would you configure fish to use something that doesn't lean on arrows? ^r has its own useful power that can be separate from my use-case of arrows mentioned above, if not just bc you don't have to move off the homerow ;)


You can press ^E to complete the current autocompletion, or keep typing a little more to disambiguate if needed.

edit: this originally said ^D, which is EOF, not autocomplete :)


Is possible to change the keyboard shortcut? Moving fingers from arrow keys and back is definitely slower than hitting ctrl-r


You can use ^p/^n


It lacks "ctrl+r" because it does history search even better than bash. It shows auto-suggestions based on your history. I find ctrl+r when I'm in bash kind of annoying, and not as good at searching.


And bash lets you accidentally screw up the history, because it's editable by default, and just weird ^p/^n behaviour


I am using fish along with fzf[1] and it makes `ctrl-r` even better.

[1] https://github.com/junegunn/fzf


Good idea, will try it.


The default mode in fish is Ctrl-R mode, the shortcut is redundant.


There's a long issue thread on this spanning since 2013:

https://github.com/fish-shell/fish-shell/issues/602

And to clarify, I understand Fish has autocomplete as good or better than bash but not having the keyboard shortcut as ctrl-r is what's making it hard to get accustomed to since I jump around servers where only bash is available and have to use ctrl-r extensively.


Can't remember if it's something special I did with my fish config but ctrl+r works for me and is actually better than bash.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: