Fish 1.23.0 is the first release in a very long time and brings many new and exciting features to the table.
If, when performing tab completion, no exact matches are found, fish uses case insensitive matching to find alternative matches.
The up and down arrows now move up and down in the text when editing a multiline command. The still retain their meaning of performing forward/backward history search when used at the top/bottom of the command, though.
Fish 1.22.0 features a large number of new features. These are the most important ones:
Fish now supports the editing of commands that span multiple lines of input. When pressing the enter key while editing an unterminated block command, such as a for loop, the enter key will only insert a newline, and fish will not attempt to execute the unfinished command. It is also possible to enter a newline that will not cause programexecution by either backslash escaping it or by using Alt-enter.
The new multinline editing also comes with automatic indentation built in.
The memory usage in fish has been significantly decreased. This is mainly caused by two improvements. The first one is that automatically loaded functions and completions are now automatically unloaded when they aren't used. The second one is that instead of loading the history file into memory, fish now uses the mmap function to map the file contents into memory. the advantage of this method of accessing the history file is that a single copy of the history can be shared by all running fish instances.
The history file is occasionally saved and reloaded while using fish. This means that in case of a crash or a power failure, the entire fish history will not be lost. It also means that when running multiple simultaneous fish sessions, commands used in one session may be accessed through the history search commands from the other running shells. The history implementation always makes sure that commands entered in the current session are always last in the history list.
The '**' wildcard can now be used to match either files or directories. This makes the wildcard more consistent with '*'. To get the old behaviour, simply use '**/'.
All fish configuration files now reside in $XDG_CONFIG_HOME/fish. If $XDG_CONFIG_HOME is unset, it defaults to ~/.config. This change makes fish conform better with freedesktop.org guidelines, reduces file clutter in the users home directory and means that there is a single location for all user configuration files. The names of various configuration files has also been changed in order to make them more consistent.
When starting an interactive session of fish 1.22.0 for the first time, fish will automatically move the old configuration files to their new location.
The only major syntactical change in fish 1.21.0 is support for
dynamically loading shellscript functions when needed. The idea
is very simple: To add a shellscript function named foo, simply
create the file foo.fish somewhere in the search path defined by
the environment variable $fish_function_path. The
default value for this variable contains ~/.fish.d/functions,
/etc/fish.d/functions and $PREFIX/share/fish/functions, meant to
be used for user specific functions, functions installed by the
sysadmin, and functions included with the shell itself,
respectively. There are some noteworthy details about the
implementation of functions:
Fish version 1.20.0 contains a new syntax for the short-circut commands 'and' and 'or':
make; and make install; or make cleanwill make the program, and if that suceeds, the program will be installed. If either of the previous commands fail, the directory will be cleaned.
1.20.0 is also the first version of fish with i18n support, i.e. support for translations and other localization support. This version only contains translations to swedish, but more translations will hopefully be coming soon. If you are interested in translating fish, see these notes on how to get started.
Fish version 1.18.0 contains no major new features. The most significant change is how wildcards that result in no matches are handled. Just like in csh, if no wildcarded arguments produce matches, the command will not to be executed. 1.18.0 also contains several bugfixes, most notably fixes for installing the configuration files into a location other than /etc.
Fish version 1.17.0 contains two major new features.
The ** wildcard can be used to match a directory
and all of its subdirectories. For example, given the
directories
doc doc/html user_doc user_doc/htmlthe string
**l will match doc/html
and user_doc/html. The ** wildcard
will only match directory names, not file names. The recursive
wildcard matching feature has been borrowed
from zsh, but the ability to mix
recursive wildcards with other tokens, such
as user**/ is unique to fish.
Posix-compatible shells have always made a distinction between
single and double quotes, i.e. "" vs. '', where double quoted
strings are subject to variable expantion and command
substitution. In order to make the language smaller and simpler,
fish has ignored this difference. Another reason for ignoring
this difference is that Posix shells often need to make sure
that a variable won't be tokenized on spaces by using code
like "$foo", but fish does not tokenize variables
on whitespace, so this has not been an issue in fish.
A large number of users have complained about this difference,
and preferring the Posix syntax, since it allows for easier
concatenation of strings with variable contents. There are also
some situations where the fish method of handling variable
expantion is not ideal. Simply writing $foo will expand $foo to
the same number of arguments as there are array elements in the
$foo variable. A non-array variable in this context is the same
thing as an array with one element, and an undefined variable is
the same as a variable with zero elements. This is very often
convenient, but in some cases, it would be better if the
expantion always resulted in exactly one argument. One example
of such a situation is the test command. The code test
$LANG = en_US might give unexpected results if $LANG is
undefined, or if it is defined to be an array. Because of this,
the syntax "$LANG", as seen in Posix, is now
supported in fish. A variable expantion within double quotes
will always expand to exactly one argument. If the variable does
not exist, the argument will be the empty string, if the
variable is an array, the elements will be separated by spaces.
Fish version 1.16.0 contains several major new features. Here is a summary:
Fish 1.16.0 features a generic event delivery framework, which can be used to run a set of commands on a specified signal, on a variable update or on job exit. Future Fish versions will probably copntain additional event triggers.
A simple example of how to write an event handler, namely
printing a notification message every time the
variable $some_var changes:
function some_function --on-variable some_var echo \$some_var changed to $some_var endFor more information on how to define event handlers, see the function documentation.
Posix shells feature a syntax that is a mix between command
substitution and piping, called process substitution. It is used
to send the output of a command into the calling command, much
like command substitution, but with the difference that the
output is not sent through commandline arguments but through a
named pipe, with the filename of the named pipe sent as an
argument to the calling program. I do not wish to add such a
feature to fish, since I feel that it is far to similar to
already existing fish concepts to warrant inclusion. But there
are still many use-cases where it might be desirable to have
some form of process substitution workalike. Therefore, fish
1.16.0 contains a psub shellscript function, which
when combined with a regular command substitution provides the
same functionality.
| bash syntax |
diff <(sort foo.txt) <(sort bar.txt) |
|---|---|
| fish syntax |
diff (sort foo.txt|psub) (sort bar.txt|psub) |
The vital difference is that the fish implementation is done
entirely as a shellscript function. It is also worth noting that
the bash syntax is whitespace
sensitive, < (...) is not interpreted as a
process substitution.
When a command outputs large amounts of information,
like make often does on failiure, it is convenient
to use a pager to search out the useful parts. When the output
is directed to stdout, this is not a problem, since you can use
a pipe to page the input through your pager of choice. But such
output is often written to another file descriptor, such as
standard error. For this reason, fish now allows you to specify
which file descriptor should be used to send output to a
pipe. The syntax is the same as the one used for regular io
redirection:
make fish 2>|less
Two builtin functions from bash have been implemented in fish, ulimit and umask. ulimit is a fish builtin function, while umask has been implemented as a shellscript function, in order to keep the shell as small as possible. The functions behave identically to the bash versions, except they support GNU-style long switches, and ulimit does not support some
Fish version 1.15.0 contains several smaller changes that to make fish more consistent and makes fish handle rare corner cases correctly. The largest internal changes come from attempts to better deal with concurrency issues and error handling.
Two changes to how variable scope is resolved have taken place.
The first change is that if a variable is set with an explicit scope, and another variable with the same name already exists in a different scope, the second variables value will not change. The reasoning behind this is that it is often desirable to use variable in a function scope and be sure that global variables with the same name won't be accidentally overwritten.
For an example of what this change means, consider the code
set foo global begin set -l foo local end echo $fooThe output in previous versions of fish would have been an empty line, since the local foo variable would have overwritten the global foo, and once the local foo went out of scope, there would be no variable called foo left. The new behaviour is to output
global, since the global value for foo is not
overwritten.
The second change is to the default scope of variables. Previously, when creating a new variable without setting the scope, the innermost block scope was used. The new rule is that the innermost function scope is used instead. (Or global scope if not in function scope.
To demonstrate this change, consider the following code:
function foo begin set bar 'defined' echo Inner function scope, \$bar is $bar end echo Outer function scope, \$bar is $bar end foo echo External scope, \$bar is $barThe old behaviour would be to print
Inner function scope, $bar is defined Outer function scope, $bar is External scope, $bar isbut with the new behaviour, the output is
Inner function scope, $bar is defined Outer function scope, $bar is defined External scope, $bar is
It is now possible to create variables which have no value. Previously, when attempting to create such values, the value was changed to the empty string. This may seem to be the same things, but the empty string as an argument string of length 0, it will be sent to subprograms as an argument, whereas an empty variable is nothing at all. This difference is important in many situations, and the previous syntax lead to awkward syntax problems in some situations.
The begin and else commands no longer require a semicolon before the next command.
The keybinding parser has gotten several improvements.
Meta-q: exit
can be used to bind keys to actions.
"\x88": backward-delete-char.
The main new feature in this release is the addition of universal variables. Universal variables are shared between all running fish instances of a given user. They are also automatically saved on exit. Universal variables have mainly two uses:
To define a universal variable, use the -U or --universal switch for set, as in set -U EDITOR ed.
To see universal variables in action, start two fish sessions side by side, and issue the following command in one of them set fish_color_cwd blue. Since fish_color_cwd is a universal variable, the color of the current working directory listing in the prompt will instantly change to blue on both terminals.
Several new builtins have been added in this release. Most significant are the or and and builtins. These commands operate on the two commands directly following them. The first one is executed, and on sucess (and) or failiure (or), the second command is also executed. This allows much terser error handling than using conditional blocks.
#If test fails, call exit or test $status = 0; exit 1 #If setup suceeds, call do_stuff and setup; do_stuffMultiple or and and commands can be stacked together, resulting in so called 'reverse Polish notation' semantics.
The not and begin builtins are convenience functions. not negates the exit status of the command following it, and begin opens up a new block, which makes begin equivalent to if true.
The type shellscript for determining the type of a command is identical to the Posix builtin with the same name, except it also supports GNU style long options.
There are quite a few new features in this release, here is a rundown of a few of them:
Fish now allows you to redirect IO from blocks and functions without any restrictions.
# Read one line at a time from a file in a loop cat foo.txt | while true; read line; ...; end # Pipe output of function into another function function foo; ...; end function bar; ...; end foo|bar # Pipe output of block through another process for i in *; ...; end | grep ...
Most of these have always been possible to do in other shells, but as far as I know, no other shell allows you to have multiple functions in the same job (Piping through aliases is possible, but aliases are very limited).
Users of systems with deb- or rpm-based package management can now complete package names using apt-get, rpm and yum.
Several new commands have gotten new or updated command specific completions. These include diff, top, kill, ps, apropos and wget.
It is now much easier to specify that some completions should only be used when some special criteria is met, such as the presence of a specified switch. Among the command-specific completions that take advantage of this are:
Fish 1.13.0 uses approximately half the memory and half the CPU time at start up compared to previous releases. Most of this improvement comes from the fact that fish no longer loads the entire database of command-specific completions on startup. Completions for a command are instead loaded whenever the user first uses a command.
Completing command names is also faster, since fewer files are stat:ed, and the command description lookup implementation is much faster.
The commands pushd and popd, well known to users of bash and other shells, are now available in fish. Also, a directory history, accessible through the nextd, prevd and dirh commands have been introduced. These commands are all implemented as shellscript functions, not as builtins, so as not to bloat the core shell.
It is now possible to erase elements from an array. Use the command set -e foo[1 3 7] to erase the first, third and seventh element of the array foo.
Keyboard shortcuts the move or erase one word now consider any non-alphanumeric characters to be word-delemiters.
Fish no longer forks when running subshells. This means that fish never ever uses a subprocess to parse any of its commands or execute builtins, resulting in that builtins and shellscript functions that change the state of fish, such as set, can be safely used in subshells.
Specifying arguments containg characters not on a standard keyboard is now much easier, since fish supports the standard C escape sequences for octal and hexadecimal ascii characters and hexadecimal unicode characters. For example, to write out an ellipsis to the screen, simply write echo \u2026.
This page was last updated on October 3, 2005. If you have comments on this page, please contact the webmaster.