
Fish: A user-friendly command line shell for macOS, Linux, etc - NanoWar
https://fishshell.com/
======
ridiculous_fish
Hey all, one of the fish devs here. It's awesome to see all of the comments
and happy users.

We are in the process of scoping a major release (fish 3.0) that can include
major syntactic changes. If there's an aspect of fish you would like to see
changed, now is a great time! Of course we'll read the comments here, and our
issues page [1] is where discussion happens.

We're also welcoming new contributors. It's easy to get started writing
completions or with the issues labelled "easy-pick". The core code base is
reasonably modern C++ too.

[http://github.com/fish-shell/fish-shell/issues/](http://github.com/fish-
shell/fish-shell/issues/)

~~~
techdragon
I see that [https://github.com/fish-shell/fish-
shell/issues/3341](https://github.com/fish-shell/fish-shell/issues/3341) is
scheduled for 3.0. This is also marked as the fix for the broken/invalid YAML
format that is used for storing the shell history [https://github.com/fish-
shell/fish-shell/issues/2258](https://github.com/fish-shell/fish-
shell/issues/2258)

I implore you to NOT use JSON or ProtocolBuffers, neither are appropriate
formats for configuring my shell, or storing long sets of textual data.
Protocol Buffers is hardly the kind of format I want to parse and read my
history in, and JSON is a less than ideal configuration format for many
reasons.

[https://github.com/vstakhov/libucl](https://github.com/vstakhov/libucl) UCL
(Universal Configuration Language) is a much more appropriate format for
configuring programs than JSON, and is has been accepted as standard for use
configuring all tools included in the FreeBSD operating system.

I also suggest you consider using a different language to store shell history,
since shell history and shell configuration are two very different jobs with
different goals and trade offs. I personally would suggest a simple safe
format like TOML [https://github.com/toml-lang/toml](https://github.com/toml-
lang/toml) for storing the history.

But If you do want a single format for both configuration and history, I would
implore you to pick TOML not JSON or Protocol Buffers.

~~~
__sr__
Out of the mainstream formats, JSON is among the easiest to parse - thanks to
the CLI tool jq. Does UCL have something equivalent?

Protobuf (or any other binary format) has the benefit of being faster to load,
but I agree - it should not be be used to store things like history. It should
be easy to parse history without having to write code. And with Protobuf, you
need the schema.

If a binary format is going to be used, it should be optional - or perhaps
there should be tools to convert the history file to/from a plaintext format.

~~~
techdragon
There is uclcmd
[[https://github.com/allanjude/uclcmd](https://github.com/allanjude/uclcmd)]
which could do with some more work but was created with the intent of being a
UCL equivalent of JQ.

Also since he’s the kind of person that a HN reader will probably Ike to know
more about. The original author of the aforementioned uclcmd, Allan Jude
[[http://twitter.com/allanjude](http://twitter.com/allanjude)], is the former
host of the TechSNAP podcast
[[http://www.jupiterbroadcasting.com/show/techsnap/](http://www.jupiterbroadcasting.com/show/techsnap/)],
current host of the BSD Now podcast
[[http://www.jupiterbroadcasting.com/show/bsdnow/](http://www.jupiterbroadcasting.com/show/bsdnow/)],
a current member of the FreeBSD Core team, and co-authored not one but two
books on the ZFS file system FreeBSD Mastery: ZFS
[[https://www.amazon.com/FreeBSD-Mastery-
ZFS-7/dp/0692452354/](https://www.amazon.com/FreeBSD-Mastery-
ZFS-7/dp/0692452354/)] and FreeBSD Mastery: Advanced ZFS
[[https://www.amazon.com/FreeBSD-Mastery-Advanced-
ZFS/dp/06926...](https://www.amazon.com/FreeBSD-Mastery-Advanced-
ZFS/dp/0692688684/)]

------
burke
I used fish twice for about a year each time, but I keep switching back to
zsh, because:

* The main things I like about fish are predictive history completion and syntax highlighting, both of which work about the same with a pair of zsh plugins;

* The syntax occupies what is, for me, an awkward middle ground: it's a bit better than POSIX syntax if POSIX shells didn't exist, but not enough better that I care to juggle the two syntaxes;

* I don't like that fish tries to be "helpful" in certain cases such as lying to you about the delimeter actually used by $PATH.

I have a couple of specific gripes about the syntax, which aren't really
inherent issues so much as unimplemented features.

I think if I was going to deviate from a POSIX shell, the alternative would
have to be more better than fish to be worth it.

~~~
davemp
Out of curiosity, what use case do you have that makes a POSIX shell a big
deal?

I’ve never had issues as a somewhat heavy user.

~~~
zeveb
> Out of curiosity, what use case do you have that makes a POSIX shell a big
> deal?

Running on a POSIX system, there are decades' worth of shell snippets out
there which don't work with fish, but do with sh, ksh, bash & zsh.

Fish is just gratuitously incompatible. Having fish-users on a team is a pain,
because they'll write everything in fish and either not bother producing sh
equivalents, or produce insufficiently-tested sh equivalents. It's just a lot
of pain and bother, and what's the benefit? Zsh does everything fish does and
more, so why not just use it?

Edit: I just wish that the original fish developers had chosen to implement
all their cool features _and_ be sh-compatible, or at the very least had
exercised some wisdom in where they chose to break compatibility. Instead, it
very much feels like a 22-year-old's project: full of ideas, some good & some
bad, and needlessly without respect for the past. I've no problem with
rejecting the past when the past is broken (and sh _is_ broken in places); my
problem is with the equivalent of saying, 'hey, English spelling is terrible,
soh Aiv dəseidid tū dəvelup mai ohn.'

~~~
geoelectric
Back in the day I used to use csh and tcsh, both of which had famously
landmine-laden scripting gotchas. So, I wrote my scripts in sh or bash. Now
that I use zsh mostly, same thing, I don't actually write my scripts in zsh--
especially for production, I write them in sh or bash. zsh for me is an
interactive CLI-only tool. Honestly, I think the problem here sounds more
about not standardizing on a common denominator for shared scripts.

Where stuff like fish is a pain for me is with apps that for whatever reason
need shell integration (virtualenv, for example). Non-POSIX shells end up
being an afterthought there, so you end up with no or buggy support, and end
up having to find some other custom variant (virtualfish, etc.) to get good
behavior. Sticking with a more mainstream shell tends to be safer there, and
zsh barely makes it over that line.

------
xiaq
Shameless plug: Elvish is another non-POSIX shell aiming at interactive
friendliness and saner scripting: [https://elvish.io/](https://elvish.io/)

Some highlights:

* It comes with helpful interactive features, like syntax highlighting and on-the-fly error checking; enhanced history searching with ^R; directory history and a Ranger-inspired "navigation mode" (see homepage for demos).

* It supports some advanced (in shell standards) programming concepts, like lambdas, namespaces, nestable maps. It also has some pretty powerful API for interactive features. These two aspects work hand in hand and offers quite some customization possibilities. In fact, one user implemented interactive history expansion (!! !$ !1) himself: [http://zzamboni.org/post/bang-bang---shell-shortcuts-in-elvi...](http://zzamboni.org/post/bang-bang---shell-shortcuts-in-elvish/;) his configuration file is also worth readng: [http://zzamboni.org/post/my-elvish-configuration-with-commen...](http://zzamboni.org/post/my-elvish-configuration-with-commentary/).

* A lightweight builtin package manager is in the work.

* It is written in Go and comes as a statically linked binary.

* A native Windows port is under way, in case you care :)

------
djsumdog
I've been using fish for 3 ~ 4 years and I love it. It's come a long was in
its development and it's interesting to watch as so many of the bugs have been
resolved. Today's fish is incredibly stable and solid. The history,
highlighting and completion are well beyond what I've seen in other shells (at
least not without adding additional plugins).

I still write scripts in bash for compatibility (when I have to; I try to use
Python whenever it's an option), but for my interactive shell, fish is really
amazing and I'd hate to go back to anything else.

------
mocko
Happy user here. If you spend a lot of time in the shell fish is totally worth
checking out.

Good points:

* Fish's completion sure saves a lot of typing

* `brew install fish` on osx

* Config in ~/.config/ rather than cluttering up the root of your homedir

* Can change many settings without needing to edit config directly - eg. `set -U fish_user_paths $fish_user_paths ~/path/name`

Bad / not intended for:

* It's not for scripting. Just use bash for that.

* I've found appending to env vars to be fiddly. Maybe I'm doing it wrong

* pyvenv's bin/activate.fish was broken for a long time (not fish's fault!)

~~~
mistersys
Just curious, since their website pretty clearly points out "sane scripting"
as a high point, what makes it bad for scripting from your perspective?

~~~
vanderZwan
Not GP, but since 90% of of my sporadic scripting is _" searching on SO how to
do something somewhat complicated that I'll never do again so it's not worth
the time to learn how to master it"_, bash is (oddly enough) a lot easier to
use here since looking up how to do it in Fish is a lot more hassle.

Similarly, if you want your code to be portable, bash is a safer bet.

~~~
mocko
I put that badly. Fish certainly does support scripting, but as a relatively
niche piece of software you get bad portability (everything has bash) and poor
maintainability (because everyone else scripts in bash). Fish is a great shell
and maybe this will change, but at the present time I'd be doing my clients a
disservice if I wrote them tools in a language few others could work with.

------
akavel
Whenever I'm reading about some alternative shell and thinking about
switching, I'm afraid of losing my proficiency in bash. For better or worse,
it's the _de facto_ standard in scripting, so I see it as an important skill.
How does this work for those of you who risked and switched? Don't you feel
some kind of schizophrenia, or accidental cross-polination typos/mistakes? How
does it work when you login to some remote machine, do you have the alt. shell
installed everywhere?

~~~
okonomiyaki3000
I have the same problem. I mainly use zsh because it's not drastically
different from bash but still offers some useful things that bash lacks. But,
honestly, we should just bite the bullet and move on to something better. Yes,
we will still need to write scripts in bash from time to time and maybe we'll
need to look up a few points that we've forgotten but we won't forget the
fundamentals and that's all you really need. Well, that and a web search.

~~~
chubot
FWIW I'm working on a bash-compatible shell:

[http://www.oilshell.org/blog/](http://www.oilshell.org/blog/)

If nothing else, I have thousands of lines of my own shell scripts that I
don't care to move to a different shell syntax that's not obviously better :)

I'm designing a new shell language which bash can be auto-converted to. This
is a lot of work and the plans might change, but the beginnings of it are
here:

[http://www.oilshell.org/blog/2017/02/05.html](http://www.oilshell.org/blog/2017/02/05.html)

[http://www.oilshell.org/blog/2017/02/06.html](http://www.oilshell.org/blog/2017/02/06.html)

------
Afforess
I love fish shell, I love the autocomplete, but I've been forced to switch
back to bash lately, because fish syntax is just different enough from bash-
isms to break too much scripts / tools / commands.

I know I could just invoke bash, but prefixing commands with "bash -c '" is
tiring and papercuts are why I switched to fish in the first place. I wish
bash had a sane auto-complete prediction like fish.

~~~
mixmastamyk
Fish doesn’t break scripts, they use whatever interpreter you specified when
you wrote them.

I use fish interactively and write very simple scripts in bash and the more
complex in Python.

~~~
Skunkleton
Maybe op is sourcing said scripts instead of executing them?

------
dllu
Fish is really great for using it in your terminal. Autocompletion, fuzzy
matching, and so on, are amazing.

Unfortunately, although it is fully scriptable, writing scripts in Fish feels
a little clunky at times. For example, I wanted to test if $dest exists, and
if not, whether $src is newer than $dest. Since there are no && or ||,
parentheses are used for command substitution, and the Fish version of "test"
has no -nt to check if a file is newer, I have to do this:

    
    
        if begin; not command test -f $dest; end; or begin; command test $src -nt $dest; end
            # do something
        end

~~~
nyolfen
use ; in place of &&

~~~
Rebelgecko
I think you should actually use "; and" in place of &&. That said I still wish
fish support && and ||, if only for the times when I copy and paste some one-
liner off of stack overflow and have to rewrite it.

------
lvh
I use fish as my primary shell. I've ran into a few issues where it broke
existing fish scripts, and, uh, let's just say some of the developers (not
'ridiculous_fish) were less than stellar in their response. (I get it. It's
open source. You don't owe anyone anything: but you also don't have to be a
jerk about it, and I also don't owe you using your software.)

My original reason for using fish was onboarding junior engineers. I had a
pretty fancy zsh/emacs setup, and they'd ask me how to make their shell do
that (reminder: on macOS you get bash3.2 by default!). So I switched to
fish/spacemacs, so the answer isn't "uh sure you can rsync 50MB of accrued
elisp".

Result: I have a nice zplug[0] setup now:

    
    
      > cat /usr/local/opt/zplug/packages.zsh
      zplug "zsh-users/zsh-syntax-highlighting"
      zplug "zsh-users/zsh-history-substring-search"
      #zplug "zsh-users/zsh-autosuggestions"
      zplug "zsh-users/zsh-completions"
    
      #zplug "plugins/git", from:oh-my-zsh
      #zplug "plugins/github", from:oh-my-zsh
      #zplug "plugins/fossil", from:oh-my-zsh
    
      #zplug "plugins/docker", from:oh-my-zsh
      #zplug "plugins/docker-compose", from:oh-my-zsh
    
      #zplug "plugins/python", from:oh-my-zsh
      #zplug "plugins/pip", from:oh-my-zsh
    
      zplug "plugins/lein", from:oh-my-zsh
    
      #zplug "plugins/autojump", from:oh-my-zsh
      #zplug "plugins/command-not-found", from:oh-my-zsh
      #zplug "plugins/gpg-agent", from:oh-my-zsh
      #zplug "plugins/ssh-agent", from:oh-my-zsh
      #zplug "plugins/thefuck", from:oh-my-zsh
    
      #zplug "plugins/aws", from:oh-my-zsh
      #zplug "plugins/osx", from:oh-my-zsh
      #zplug "plugins/battery", from:oh-my-zsh
      
      zplug "tweekmonster/nanofish", as:theme
    

Still easy to reproduce. Maybe consider some of those plugins. You don't have
to give up being POSIXy. Whether or not that's good or bad, I leave up to you
:)

(Commented out bits are things I'm playing with: mostly to improve shell
startup time.)

[0]: [https://github.com/zplug/zplug](https://github.com/zplug/zplug)

------
qaute
Related: xonsh ([http://xonsh.org](http://xonsh.org))

It's a Python-based shell that attempts to be somewhat bash-compatible (for
ease of use over, e.g., IPython). Instead of making a new scripting language
(fish), go all in.

Pros: scripting is amazing. ( while True: ls ~ ) Cons: can be a bit slow
(because Python interpreter).

------
tuvistavie
It is also worth noting that the ecosystem around fish is quite developed,
making it easy to get easy integration and completions for most well-known
tools.

oh-my-fish [1] plugins is a good place to see (part of) what is available

[1]: [https://github.com/oh-my-fish](https://github.com/oh-my-fish)

------
chrisweekly
I'm happy w/ zsh but have played a bit w/ xonsh (a POSIX-compliant shell w/
deep python integration), because my cousin is a core contributor. Curious if
others here have tried xonsh and what your experiences have been.

[https://xonsh.org](https://xonsh.org)

~~~
BeetleB
I use xonsh on my Windows machine at work (too lazy to learn Power Shell).
Very happy with it, and a quick way to get a bash type shell on Windows. Not
the most stable beast (e.g. yesterday I typed "pwd" and it crashed and
returned me to the Windows prompt).

I also use it on my home computer (on top of zsh) and am pretty happy with it.

It is a bit slower in terms of response time, but that's OK. Most of the
problems I had with it have been resolved after filing bug reports. The only
annoyance is that when I quit Midnight Commander, I'm back in the directory I
started with. But that's a MC problem, and not xonsh. Every shell out there
has a special wrapper script to handle MC. I just need to understand the one
zsh uses and port it over to xonsh.

The two best parts about xonsh:

1\. You can use the command line like you would a Python interpreter. Need to
do a quick calculation? Just type it in and press Enter.

2\. No more obnoxious bash/zsh scripting. Write all your shell scripts in
Python!

------
xfr
Ctrl-R and Ctrl-S please. Using the arrow keys for searching through history
quickly (i.e. without leaving the home row) sucks.

~~~
realusername
+1. If some developer reads this, Ctrl+R is the only missing thing I can't
imitate from bash.

~~~
fallensatan
I know this might not be what you'd want, but I'm doing this with fzf[0]. I
have something like this as an alias:

    
    
      eval (cat ~/.local/share/fish/fish_history | grep 'cmd:' | cut -c8- | fzf --tac)
    

and then I simply bound it with `\cr`. It doesn't exactly replace Ctrl-R
functionality but it suits my need.

[0] [https://github.com/junegunn/fzf](https://github.com/junegunn/fzf)

------
crispinb
The great thing about fish for me is that comes so nicely set up on first
install that, a few path additions aside, I don’t have to mess with it. Any
time spent on shell configuration is time wasted from my perspective.

This in turn means I’m willing to install it with no hesitation in all my
local and remote logins, so I have a uniform simple setup everywhere.

------
canjobear
I've used fish as my shell for over five years. Thanks to the developers!

One issue is the behavior of globs. I often want to do "scp host:directory/*
." but you can't do that in fish, so I drop to bash. That's pretty much all I
drop to bash for.

~~~
rufugee
scp host:directory/\\* .

~~~
jhasse
Also possible:

    
    
        scp 'host:directory/*' .

------
jboynyc
I switched to Fish about half a year ago after reading Julia Evans' essay
singing its praises: [https://jvns.ca/blog/2017/04/23/the-fish-shell-is-
awesome/](https://jvns.ca/blog/2017/04/23/the-fish-shell-is-awesome/)

I think what convinced me was the last point: if you really can't do what
you're trying to do in Fish, firing up sh/csh/ksh/bash/python/xonsh costs
virtually no effort.

~~~
zeveb
> if you really can't do what you're trying to do in Fish, firing up
> sh/csh/ksh/bash/python/xonsh costs virtually no effort.

But of course having to recall how to do something in a POSIX-compatible shell
can cost if you've been using a POSIX-incompatible shell for years. Memory and
experience do fade over time.

------
eltoozero
I’ve been enjoying fish for the handy tab complete of command line options,
the interactive history, and it’s pretty.

I’m certainly guilty of finding one-liners online which frequently fail in
fish, which puts me in the position of either actually learning what the terse
statement actually does and re-implementing it in the fish “c-like” syntax, or
I just drop into bash then get on with my business.

Really happy with it, but I know I get sideways stares from graybeards and
gurus who consider it the small-batch, fixed-gear, “Crocs” of shells.

------
kmm
I've been using fish for a few years now, and it has made bash feel not just
outdated, but completely obsolete. I am at loss for why it hasn't taken the
entire world by storm.

------
hecturchi
I use fish since the first time I tried it some years ago because it upgrades
your user experience.

I don't understand what the fuss with not being compatible with bash is. Bash
scripts run with #!/bin/bash in bash. If you need to write/copy&paste some
bash code just jump to a bash shell. In the meantime, fish will save you lots
of time on your daily regular shell usage.

------
NuSkooler
Fish shell is the first thing I install on my setups. Been using it for a few
years now and love - and advocate for - it.

------
anonfunction
If you like fish but miss the plugin ecosystem of zsh you might be interested
in the fish-shell plugin manager, fisherman. I've really been enjoying fish
with z and fzf.

[https://github.com/fisherman/fisherman](https://github.com/fisherman/fisherman)

------
thibran
Thanks for the awesome fish shell – my beloved default.

For improvements here are two things I wish where possible in fish:

* The ability via a flag to say that a fish-function should not interpret passed function-arguments. This would enable us to pass e.g. URLs to a function without quote them, which is somewhat anointing right now. So this change would be a nice usability improvement.

* I would like to be able to write dynamic completions, containing of a key-value pair. The key should be displayed and if the user selects a completion-item, the corresponding value should be passed to a fish-function from which arbitrary actions could be triggered. Maybe supporting JSON input here would be nice too.

~~~
faho
>* The ability via a flag to say that a fish-function should not interpret
passed function-arguments.

Note that functions already don't expand the passed arguments. Fish expands
them _before_ executing the function, so what you are asking for is a major
layering violation.

E.g. you can do this:

    
    
        function a
           b $argv
        end
    
        function b
           string escape -- $argv
        end
    
        a 'something * with ? loads {} of $pecial char"acters'
    

and the output will come out right. You only need to quote it once.

>This would enable us to pass e.g. URLs to a function without quote them

I'm assuming what you are asking for isn't _passing_ URLs to functions, but
rather _pasting_ URLs into the commandline.

In which case fish has a feature I like to call "magic paste". When you paste
with an open single quote (`somecommand '`), it'll escape single quotes (and
backslashes). So you type the closing single quote and your argument will be
passed to the command you are calling as the exact text you pasted.

>The key should be displayed and if the user selects a completion-item, the
corresponding value should be passed to a fish-function from which arbitrary
actions could be triggered.

We have "descriptions" for completions, which will be displayed _alongside_
the argument (i.e. the "value"). To generate them dynamically, simply separate
them with a tab character (`\t`) from the argument, and separate these pairs
with newlines.

So

    
    
        printf '%s\t%s\n' 'argument' 'description' 'argument2' 'description2'
    

will be displayed as

    
    
        argument (description)    argument2 (description2)
    

We use this to great effect in numerous places. E.g. the git completions will
offer commit hashes with the summary line as description, so when I type `git
revert <TAB>` I get something like

    
    
        0a129475    (Replace opts.stdout with opts.to_stdout)
    

I'm not sure I like the idea of hiding the real argument from the user.

>Maybe supporting JSON input here would be nice too.

The best completions are those that actually call the stuff they are
completing (because that makes them really reactive), and not many commandline
tools actually generate JSON. Anything in particular you're thinking about
here?

(And now I'm hoping that HN doesn't hopelessly mangle this comment)

~~~
thibran
# First Topic

The idea would be to be able to write something like this:

    
    
        function yt --pure
            youtube-dl $argv
        end
    

The parser should stop interpreting arguments after the yt function call and
pass the args as strings to the function as before.

Then such a call would be possible: yt
[https://www.youtube.com/watch?v=mqma6GpM7vM](https://www.youtube.com/watch?v=mqma6GpM7vM)

# Second Topic

I wrote a little utility [1] to quicker navigate on the file system. Right now
I have two commands:

    
    
        m  [folder]  // goto highest ranked folder
        mm [folder]  // list results for folder-keyword
    

I would like to be able to write 'm foobar' and then press tab to get a
vertical completion-list. When the user selects a completion-list-item I would
like to pass the result-path to the cd command. Some time ago I tried to write
such a completion, but failed – that's why I still use a separate mm-function
to list search results.

[1]: [https://github.com/thibran/maybe](https://github.com/thibran/maybe)

I think JSON might be a good choice here because it would simplify the
interaction with the completion program for advanced completions. Passing all
those flags – mixed with some other shell function calls – to the 'complete'
program is a bit cumbersome. My dream would be to have something like
'complete -c maybe --json [maybe-flag-to-generate-json-output]' and handle
everything inside the application.

    
    
        {
          "fish_completion_version": 1,
          "header": "optional, completion header",
          "orientation": "vertical",
          "on_single_result": "optional, choose-item or display-item",
          "arguments": [
            {
              "item",
              "description",
              "optional return value, if empty return item"
            }],
          "item_handler": "optional, name of fish function to call on-item-chosen"
        }
    

I know JSON is not something you want to assemble in a script, but all
programming languages have support for it and it's easy to use.

~~~
faho
>Then such a call would be possible: yt
[https://www.youtube.com/watch?v=mqma6GpM7vM](https://www.youtube.com/watch?v=mqma6GpM7vM)

Okay, so I did understand what you are saying.

Like I said, that's a rather large layering violation, since the function has
nothing to do with the expansions happening on its arguments. They are
expanded before they ever reach the function. It's essentially allowing
functions to modify the syntax around them.

How exactly would this treat e.g.

    
    
        yt $URL/somefile
    

Would the variable still be expanded? Would an asterisk glob be? If I _did_
want it to expand something even though the function is declared "pure", how
would that work?

Now I couldn't be sure how my arguments would be interpreted, or I'd have to
go checking for everything I invoke.

I use youtube-dl myself quite often, and what I do is just type

    
    
       youtube-dl '
    

then press ctrl-v (which is a keybinding that uses xsel or pbpaste to get the
clipboard contents and insert them into the commandline) or ctrl-shift-v
(which is my terminal's paste binding). Then I press `'` again and can
download the video.

Additionally, it's looking like 3.0 will remove the `?` glob, which is the
thing that is most annoying with URLs (though "&" is also a thing).

> I would like to be able to write 'm foobar' and then press tab to get a
> vertical completion-list. When the user selects a completion-list-item I
> would like to pass the result-path to the cd command.

I would assume the reason you failed is that the argument you want doesn't
match the argument the user typed. Because fish's completions undergo
filtering (with some fuzzy-matching, so e.g. `f_c_i` matches
`fish_config_interactive`). Otherwise every completion script would have to
implement that by itself, and consistently to not confuse people.

For completions, that's the right thing to do.

What you want, I'd argue, isn's a completion. What you want is a selection
menu. Which could be implemented with fish's completion pager (we have an open
issue about making it accessible to the outside), but isn't the same thing.

JSON here is a red herring, since you don't just want to add items (with
descriptions), but also control the behavior of the pager ("orientation" and
"on_single_result"). That you could do just with arguments to this `select`
command (`list_of_items | select --orientation=vertical --on-single=choose`).

~~~
thibran
> How exactly would this treat e.g.
    
    
        yt $URL/somefile
    

> Would the variable still be expanded? Would an asterisk glob be?

No. Pure should mean don't do anything from here on, just pass the arguments
to the function.

> If I _did_ want it to expand something even though the function is declared
> "pure", how would that work?

If expanding should be possible in a pure context, then maybe by using a known
syntax like:

    
    
        yt ($URL)/somefile
    

Eshell expands Lisp code when using (lisp-code-here) which is kind of elegant.
So when in a pure context, you would have to switch to expansion-mode by using
curly braces.

------
0xmohit
5 year old feature request [0].

[0] [https://github.com/fish-shell/fish-
shell/issues/438](https://github.com/fish-shell/fish-shell/issues/438)

~~~
techdragon
I just read that entire issue and it looked dire for a while, hopefully it is
resolved properly in [https://github.com/fish-shell/fish-
shell/pull/4442](https://github.com/fish-shell/fish-shell/pull/4442)

------
dijit
I've been using fish on my laptop for some time now, it is an interesting
project and I use it personally for purely aesthetic reasons. However I have a
lot of muscle memory with bash-isms which also work in ZSH.

History expansion `!$` for example, is missing.

SDTIN redirects as I expect `<<<` etc; are also missing. And to get ^R to work
again I had to install fzf.

Now, I am fairly certain I'm doing it wrong, but I never found a good place to
read how to do it the fish way... If anyone has good replacements for the
things I've mentioned I'd be quite keen to hear them.

------
fiatjaf
Fish is great both as shell and as a scripting language.

I've written both my Trello Exporter CLI tool[0] and the first version of my
React/Browserify static site generator[1] on it.

[0]: [https://github.com/websitesfortrello/trello-
exporter](https://github.com/websitesfortrello/trello-exporter)

[1]:
[https://github.com/fiatjaf/sitio/tree/fish](https://github.com/fiatjaf/sitio/tree/fish)

------
wooptoo
I've started using fish after seeing this post. It's an incredible shell. How
come I haven't came across it in the past 10 years?

I like the scripting syntax too, so much saner than bash.

------
msluyter
It's been a while since I've tried it so perhaps someone can comment whether
things have changed or if there was something I missed. When I last tried
fish, I liked it but I couldn't get past the lack of ctrl-r (backward history
search), which I rely on extensively. I found having to reach over to the
up/down arrows too clumsy in comparison. An oh-my-zsh plugin also provides
fuzzy searching (history-search-multi-word).

Anythiing comparable now in fish land?

~~~
7scan
If you use vi mode then history can be navigated with hjkl.

------
hsson
I definitely prefer zsh. I just feel like Fish tries too hard and it's just
awkward to switch between fish and bash when frequently switching between
different machines.

------
fb03
I have fish installed because for some odd reason, the "SSH link" feature of
Midnight Commander didn't work across two servers that we use. After
installing it I could use the "Shell Link" feature and it was lovely to be
able to exchange files between servers using a 'graphical' terminal. Specially
useful with some of our devs which aren't too command line happy.

------
itsjloh
My biggest gripe is fish (I think its Fish?) trying to do DNS lookups when I
hit `ssh user@hosting-<tab><tab>`

Is there a way to disable this?

------
snvzz
I remember installing it, typing 'help', having a browser pop up as a
consequence, then uninstalling it.

Definitely not for me.

~~~
jhasse
If you don't want to leave the terminal:

    
    
        set BROWSER lynx
        help

------
Symmetry
I like fish enough that I went and added fish support to ROS when I was doing
ROS development. I still leave bash as my system shell because scripts. But
all my terminals are set to start with fish instead.

------
qwerty456127
This is amazing. IMHO Ubuntu, Elementary, OSX and other OSes that are trying
to be practical, easy and pleasurable to use out of the box should offer this
by default, together with tldr.sh.

------
kharms
Loved it a few years ago, stopped using it when I started using conda and it
didn’t support switching into those environments. I’ll try again hopefully
that’s fixed.

------
meken
Anyone use either eshell or shell mode in emacs? tramp-mode alone has been a
huge boost to my overall satisfaction.

~~~
thibran
I seriously considered using eshell (I love Lisp and Emacs dired-mode), but
ended up continuing with Fish.

Since I use the non-graphical Emacs (emacs-nox), I can easily start dired-mode
in terminal by writing: emacs .

------
baby
I've never tried it and spent the last few years relying on oh-my-zsh, is it
worth trying to switch?

------
Exuma
How's this compare to oh-my-zsh?

~~~
k3a
I tried oh-my-zsh and it was too slow for me for some reason. Returning from a
command took a second. Maybe I had some buggy plugin enabled, I don't know.

Fish is almost zero configuration and has many useful functions built-in and
they are quite fast. Unfortunatelly it doesn't use bash-style syntax like zsh
does.

------
exabrial
Wow! This is great!

Wait... Is whitespace significant?

~~~
AnthonBerg
No, not to my knowledge! It does autoindent things for you when you’re editing
multiline functions inline, but whitespace is fortunately not significant.

~~~
shmerl
Great! It's one of the things that irritates me in Python (whitespace used as
scope delimiter).

~~~
AnthonBerg
I'd go so far as state that I cannot fathom the decision to assign deep
semantic meaning to a set of invisible symbols.

------
HaoZeke
Zsh or death！

------
charlescearl
Fish is nice and I eventually learned to accept the scripting. BUT if it is
the shell for the ‘90s what is the 21st century shell?

~~~
pzone
It's a joke. The implication is that Bash was already outdated in the 90s, so
it's long past time for something new.

~~~
charlescearl
I know, just trying to be too pithy :) But will seriously look at some of the
other shells mentioned. I miss scsh.

------
Froyoh
I'm happy with plain old bash.

------
cat199
1) web based configuration? really?

2) list.reverse(macOS, Linux, and the rest of the family)

~~~
djsumdog
That is the one thing I really didn't like about Fish; that and how the help
screens use to launch in a web browser. But once you get past the initial
configuration, you never use that stuff again. Despite that fault, I still
love Fish shell.

~~~
ridiculous_fish
`help` opens in the browser, but fish also has excellent man pages for all of
its commands.

------
themistocle
Love fish, especially because of the easy configuration and out of the box
features. No need for complicated frameworks or curated dotfiles. There are
two syntax changes I’d love to see:

1\. Support for last command by !!, as in `sudo !!`.

2\. Ability to search history from a partial command like `git checkout`,
where up arrow would step backward from the present.

I wish all my tools were as friendly as fish!

~~~
faho
>2\. Ability to search history from a partial command like `git checkout`,
where up arrow would step backward from the present.

We have that feature, and it's enabled by default. Just type the partial
commandline and press up-arrow. Or do you mean something slightly different?

~~~
themistocle
That's true. Sorry for my poorly-worded English. For a small example:

    
    
        $ ls -la foo
        $ ls -la bar
        $ ls -la /
    

When I type `ls -l` and hit the up arrow, my first result is `ls -la bar` not
`ls -la /`. This is a small problem but sometimes annoying, especially after
using other shells that work differently.

~~~
faho
In this case, what most likely happens is that the first result is offered as
the suggestion - i.e. the greyed-out part in the commandline. To accept that,
press right-arrow (with the default bindings, of course).

~~~
themistocle
Thanks for the suggestion.

