Tutorial auto colouring, Man page and Make fixes

Completely fixes  and the underlying Doxygen changes that caused
it. Should make fish docs simpler and more robust, more consistent and
generally prettier.

todo:
- trap unmarked text as arguments in context
- test & fix sed portability - see in particular. (so far tested on BSD
(Mac) and GNU sed).
- test Makefile changes
- last round of aesthetic changes and getting that ascii fish in there…
This commit is contained in:
Mark Griffiths 2014-08-08 03:44:37 +01:00
parent 6513c7eab8
commit 629a39b45b
28 changed files with 637 additions and 482 deletions

6
.gitignore vendored

@ -30,6 +30,7 @@ share/man/
toc.txt
user_doc/
xcuserdata
fish.xccheckout
tests/*tmp.*
tests/foo.txt
FISH-BUILD-VERSION-FILE
@ -37,8 +38,8 @@ version
messages.pot
lexicon.txt
doc_src/fish_lexicon_filter
debug-lexicon.log
lexicon_filter
lexicon-debug.log
Fish-Shell.sublime-workspace
Fish-Shell.sublime-project
@ -47,3 +48,4 @@ doc_src/.editorconfig
lexicon.log

@ -228,8 +228,48 @@ TAB_SIZE = 8
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
ALIASES = "fish=\n<div class=\"cli\">\verbatim"
ALIASES += "endfish=\endverbatim</div>"
ALIASES = "key{1}=<b>\1</b>"
ALIASES += "key{2}=<b>\1</b>-<b>\2</b>"
ALIASES += "key{3}=<b>\1</b>-<b>\3</b>"
ALIASES += "cursor_key{2}=<b>\2</b>"
ALIASES += "fish=\htmlonly[block] \n<pre>"
ALIASES += "fish{1}=\htmlonly[block] \n<pre>"
ALIASES += "endfish=</pre>\endhtmlonly \n"
ALIASES += "asis{1}=\1"
ALIASES += "outp{1}=\1"
ALIASES += "blah{1}=#\1"
ALIASES += "cmnd{1}=\1"
ALIASES += "func{1}=\1"
ALIASES += "sbin{1}=\1"
ALIASES += "args{1}=\1"
ALIASES += "opts{1}=\1"
ALIASES += "vars{1}=\1"
ALIASES += "optr{1}=\1"
ALIASES += "redr{1}=\1"
ALIASES += "fsfo{1}=\1"
ALIASES += "path{1}=\1"
ALIASES += "clrv{1}=\1"
ALIASES += "strg{1}=\1"
ALIASES += "sglq{1}='\1'"
ALIASES += "dblq{1}=\"\1\""
ALIASES += "prmt=&gt;"
ALIASES += "prmt{1}=\1&gt;"
ALIASES += "sgst{1}=\1"
ALIASES += "mtch{1}=\1"
ALIASES += "smtc{1}=\1"
ALIASES += "eror{1}=\1"
ALIASES += "curs=_"
ALIASES += "curs{1}=\1"
ALIASES += "bold{1}=\1"
ALIASES += "emph{1}=\1"
ALIASES += "undr{1}=\1"
ALIASES += "span{2}=\2"
ALIASES += "spcl{2}=\2"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"

@ -230,43 +230,48 @@ TAB_SIZE = 4
# Simplify Fish output from Doxygen for man pages. (see fish_lexicon_filter)
ALIASES = "key{1}=<b>\1</b>"
ALIASES += "key{2}=<b>\1</b>-<em>\2</em>"
ALIASES += "key{3}=<b>\1</b>-<em>\3</em>"
ALIASES += "cursor_key{2}=<b>\2</b>"
ALIASES = "key{1}=<b>\1</b>"
ALIASES += "key{2}=<b>\1</b>-<em>\2</em>"
ALIASES += "key{3}=<b>\1</b>-<em>\3</em>"
ALIASES += "cursor_key{2}=<b>\2</b>"
ALIASES += "fish=<pre>"
ALIASES += "fish{1}=<pre>"
ALIASES += "endfish=</pre>"
ALIASES += "fish=<pre>"
ALIASES += "fish{1}=<pre>"
ALIASES += "endfish=</pre>"
ALIASES += "asis{1}=\1"
ALIASES += "blah{1}=\1"
ALIASES += "cmnd{1}=\b \1"
ALIASES += "func{1}=\b \1"
ALIASES += "sbin{1}=\b \1"
ALIASES += "args{1}=\1"
ALIASES += "opts{1}=\1"
ALIASES += "vars{1}=\1"
ALIASES += "optr{1}=\1"
ALIASES += "redr{1}=\1"
ALIASES += "fsfo{1}=\1"
ALIASES += "path{1}=\1"
ALIASES += "clrv{1}=\1"
ALIASES += "asis{1}=\1"
ALIASES += "outp{1}=\1"
ALIASES += "blah{1}= \1"
ALIASES += "cmnd{1}=<b>\1</b>"
ALIASES += "func{1}=<b>\1</b>"
ALIASES += "sbin{1}=<b>\1</b>"
ALIASES += "args{1}=\1"
ALIASES += "opts{1}=\1"
ALIASES += "vars{1}=\1"
ALIASES += "optr{1}=\1"
ALIASES += "redr{1}=\1"
ALIASES += "fsfo{1}=\1"
ALIASES += "path{1}=\1"
ALIASES += "clrv{1}=\1"
ALIASES += "strg{1}=\1"
ALIASES += "sglq{1}=\'\1\'"
ALIASES += "dblq{1}=\"\1\""
ALIASES += "strg{1}=\1"
ALIASES += "sglq{1}='\1'"
ALIASES += "dblq{1}=\"\1\""
ALIASES += "prmt{1}=\1"
ALIASES += "sgst{1}=\1"
ALIASES += "eror{1}=<b>\1</b>"
ALIASES += "curs{1}=\1"
ALIASES += "prmt=&gt;"
ALIASES += "prmt{1}=\1&gt;"
ALIASES += "sgst{1}=\1"
ALIASES += "mtch{1}=<em>\1</em>"
ALIASES += "smtc{1}=<em>\1</em>"
ALIASES += "eror{1}=<b>\1</b>"
ALIASES += "curs=_"
ALIASES += "curs{1}=\1"
ALIASES += "bold{1}=<b>\1</b>"
ALIASES += "emph{1}=<em>\1</em>"
ALIASES += "undr{1}=<em>\1</em>"
ALIASES += "span{2}=\1"
ALIASES += "spcl{2}=\1"
ALIASES += "bold{1}=<b>\1</b>"
ALIASES += "emph{1}=<em>\1</em>"
ALIASES += "undr{1}=<em>\1</em>"
ALIASES += "span{2}=\2"
ALIASES += "spcl{2}=\2"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"

@ -230,43 +230,48 @@ TAB_SIZE = 4
# Enhance Fish docs output from Doxygen. (See fish_lexicon_filter.in)
ALIASES = "key{1}=<span class=\"key\"><b>\1</b></span>"
ALIASES += "key{2}=<span class=\"key\"><em>\1</em><span>-</span><b>\2</b></span>"
ALIASES += "key{3}=<span class=\"key\"><em>\1</em><span>-</span><b>\2</b></span>"
ALIASES += "cursor_key{2}=<span class=\"key\"><b>\1</b></span>"
ALIASES = "key{1}=<span class=\"key\"><b>\1</b></span>"
ALIASES += "key{2}=<span class=\"key\"><em>\1</em><span>-</span><b>\2</b></span>"
ALIASES += "key{3}=<span class=\"key\"><em>\1</em><span>-</span><b>\2</b></span>"
ALIASES += "cursor_key{2}=<span class=\"key\"><b>\1</b></span>"
ALIASES += "fish=\htmlonly[block] \n<pre class=\"fish\">"
ALIASES += "fish{1}=\htmlonly[block] \n<pre class=\"fish \1\">"
ALIASES += "endfish=</pre>\endhtmlonly \n"
ALIASES += "fish=\htmlonly[block] \n<pre class=\"fish\">"
ALIASES += "fish{1}=\htmlonly[block] \n<pre class=\"fish \1\">"
ALIASES += "endfish=</pre>\endhtmlonly \n"
ALIASES += "asis{1}=\1"
ALIASES += "blah{1}=<span class=\"comment\">\1</span>"
ALIASES += "cmnd{1}=<span class=\"command\">\1</span>"
ALIASES += "func{1}=<span class=\"function\">\1</span>"
ALIASES += "sbin{1}=<span class=\"binary\">\1</span>"
ALIASES += "args{1}=<span class=\"argument\">\1</span>"
ALIASES += "opts{1}=<span class=\"argument\">\1</span>"
ALIASES += "vars{1}=<span class=\"variable\">\1</span>"
ALIASES += "optr{1}=<span class=\"operator\">\1</span>"
ALIASES += "redr{1}=<span class=\"redirect\">\1</span>"
ALIASES += "fsfo{1}=<span class=\"file\">\1</span>"
ALIASES += "path{1}=<span class=\"path\">\1</span>"
ALIASES += "clrv{1}=<span class=\"variable\">\1</span>"
ALIASES += "asis{1}=\1"
ALIASES += "outp{1}=<span class=\"output\">\1</span>"
ALIASES += "blah{1}=<span class=\"comment\">#\1</span>"
ALIASES += "cmnd{1}=<span class=\"command\">\1</span>"
ALIASES += "func{1}=<span class=\"function\">\1</span>"
ALIASES += "sbin{1}=<span class=\"binary\">\1</span>"
ALIASES += "args{1}=<span class=\"argument\">\1</span>"
ALIASES += "opts{1}=<span class=\"argument\">\1</span>"
ALIASES += "vars{1}=<span class=\"variable\">\1</span>"
ALIASES += "optr{1}=<span class=\"operator\">\1</span>"
ALIASES += "redr{1}=<span class=\"redirect\">\1</span>"
ALIASES += "fsfo{1}=<span class=\"file\">\1</span>"
ALIASES += "path{1}=<span class=\"path\">\1</span>"
ALIASES += "clrv{1}=<span class=\"variable\">\1</span>"
ALIASES += "strg{1}=<span class=\"string\">\1</span>"
ALIASES += "sglq{1}=<span class=\"string\">'\1'</span>"
ALIASES += "dblq{1}=<span class=\"string\">\"\1\"</span>"
ALIASES += "strg{1}=<span class=\"string\">\1</span>"
ALIASES += "sglq{1}=<span class=\"string\">'\1'</span>"
ALIASES += "dblq{1}=<span class=\"string\">\"\1\"</span>"
ALIASES += "prmt{1}=<span class=\"prompt\"\1</span>"
ALIASES += "sgst{1}=<span class=\"suggest\"\1</span>"
ALIASES += "eror{1}=<span class=\"error\"\1</span>"
ALIASES += "curs{1}=<span class=\"cursor\"\1</span>"
ALIASES += "prmt=<span class=\"prompt\">&gt;</span>"
ALIASES += "prmt{1}=<span class=\"prompt\">\1&gt;</span>"
ALIASES += "sgst{1}=<span class=\"suggest\">\1</span>"
ALIASES += "mtch{1}=<span class=\"match\">\1</span>"
ALIASES += "smtc{1}=<span class=\"search_match\">\1</span>"
ALIASES += "eror{1}=<span class=\"error\">\1</span>"
ALIASES += "curs=<span class=\"cursor\"> </span>"
ALIASES += "curs{1}=<span class=\"cursor\">\1</span>"
ALIASES += "bold{1}=<strong>\1</strong>"
ALIASES += "emph{1}=<em>\1</em>"
ALIASES += "undr{1}=<u>\1</u>"
ALIASES += "span{2}=<span style=\"\1\">\2</span>"
ALIASES += "spcl{2}=<span class=\"\1\">\2</span>"
ALIASES += "bold{1}=<strong>\1</strong>"
ALIASES += "emph{1}=<em>\1</em>"
ALIASES += "undr{1}=<span class=\"underline\">\1</span>"
ALIASES += "span{2}=<span style=\"\1\">\2</span>"
ALIASES += "spcl{2}=<span class=\"\1\">\2</span>"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"

@ -259,8 +259,8 @@ prof: all
# The sed command deletes everything including and after the first -, for simpler version numbers
# Cleans up the user_doc/html directory once Doxygen is done.
user_doc: $(HDR_FILES_SRC) Doxyfile.user $(HTML_SRC) $(HELP_SRC) doc.h $(HDR_FILES) doc_src/fish_lexicon_filter
(cat Doxyfile.user; echo INPUT_FILTER=doc_src/fish_lexicon_filter; \
user_doc: $(HDR_FILES_SRC) Doxyfile.user $(HTML_SRC) $(HELP_SRC) doc.h $(HDR_FILES) lexicon_filter
(cat Doxyfile.user; echo INPUT_FILTER=./lexicon_filter; \
echo PROJECT_NUMBER=$(FISH_BUILD_VERSION) | sed "s/-.*//") | doxygen - && touch user_doc; \
cd user_doc/html; rm -f bc_s.png bdwn.png closed.png ftv2*.png nav*.png open.png sync_*.png tab*.* doxygen.* dynsections.js jquery.js pages.html
@ -268,8 +268,8 @@ user_doc: $(HDR_FILES_SRC) Doxyfile.user $(HTML_SRC) $(HELP_SRC) doc.h $(HDR_FIL
# Source code documentation. Also includes user documentation.
#
doc: *.h *.cpp doc.h Doxyfile
(cat Doxyfile; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION)) | doxygen - ;
doc: *.h *.cpp doc.h Doxyfile lexicon_filter
(cat Doxyfile; echo INPUT_FILTER=./lexicon_filter; echo PROJECT_NUMBER=$(FISH_BUILD_VERSION)) | doxygen - ;
#
@ -360,6 +360,7 @@ lexicon.txt: doc_src/commands.hdr $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES
-e "s|'\(.*\)'|func \1|p"; \
sed <share/functions/__fish_config_interactive.fish >>lexicon.tmp -n \
-e '/set_default/s/.*\(fish_[a-z][a-z_]*\).*$$/clrv \1/p'; \
echo "sbin whoami\nsbin mkdir\nsbin basename" >> lexicon.tmp; \
mv lexicon.tmp lexicon.txt; rm -f lexicon_catalog.tmp lexicon_catalog.txt;
#
@ -373,14 +374,19 @@ lexicon.txt: doc_src/commands.hdr $(FUNCTIONS_DIR_FILES) $(COMPLETIONS_DIR_FILES
# providing suitable CSS in user_doc.css.in
#
doc_src/fish_lexicon_filter: lexicon.txt doc_src/fish_lexicon_filter.in
lexicon_filter: lexicon.txt lexicon_filter.in
-rm $@.tmp $@
# Clean the filter input comments and set the shebang as sed can reside in
# /bin or /usr/bin and some versions dont allow more than one comment!.
sed <$@.in >$@.tmp -e 's|@sed@|'"`command -v sed`"'|' -e '/^[ ]*#[^!]/d'
sed <$@.in >$@.tmp -e 's|@sed@|'"`which sed`"'|' -e '/^[ ]*#[^!]/d'
# Scan through the lexicon, transforming each line to something useful to Doxygen.
if `echo "x" | sed "/[[:<:]]x/d"`; then \
WORDBL='[[:<:]]'; WORDBR='[[:>:]]'; \
else\
WORDBL='\\<'; WORDBR='\\>'; \
fi; \
sed <lexicon.txt >>$@.tmp -n \
-e 's|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,[[:<:]]\2[[:>:]],@\1{\2},g|p' \
-e "s|^\([a-z][a-z][a-z][a-z]\) \([a-z_-]*\)$$|s,$$WORDBL\2$$WORDBR,@\1{\2},g|p" \
-e '$$G;s/.*\n/b tidy/p'; \
mv $@.tmp $@; if test -x $@; then true; else chmod a+x $@; fi
@ -485,11 +491,11 @@ common.o: $(COMMON_FILES)
# There ought to be something simpler.
#
share/man: $(HELP_SRC) doc_src/fish_lexicon_filter
share/man: $(HELP_SRC) lexicon_filter
-mkdir share/man
touch share/man
-rm -Rf share/man/man1
PROJECT_NUMBER=`echo $(FISH_BUILD_VERSION)| sed "s/-.*//"` INPUT_FILTER=doc_src/fish_lexicon_filter \
PROJECT_NUMBER=`echo $(FISH_BUILD_VERSION)| sed "s/-.*//"` INPUT_FILTER=./lexicon_filter \
./build_tools/build_documentation.sh Doxyfile.help ./doc_src ./share
#
@ -804,7 +810,7 @@ clean:
rm -f $(PROGRAMS) fish_tests key_reader
rm -f command_list.txt command_list_toc.txt toc.txt
rm -f doc_src/index.hdr doc_src/commands.hdr
rm -f doc_src/fish_lexicon_filter lexicon.txt debug-lexicon.log
rm -f lexicon_filter lexicon.txt lexicon.log
rm -f FISH-BUILD-VERSION-FILE
if test "$(HAVE_DOXYGEN)" = 1; then \
rm -rf doc user_doc share/man; \

@ -23,11 +23,9 @@ The following code will create `rmi`, which runs `rm` with additional arguments
\fish
alias rmi "rm -i"
\endfish
This is equivalent to entering the following function:
# This is equivalent to entering the following function:
\fish
function rmi
rm -i $argv
end

@ -1,5 +1,5 @@
/** \page commands Commands
/**
\page commands Commands
\htmlonly[block]
<div class="fish_left_bar fish_left_little">
<div class="menu commands_menu">

@ -1,5 +1,5 @@
/** \page design Design document
/**
\page design Design document
\htmlonly[block]
<div class="fish_only_bar">
<div class="design">
@ -41,7 +41,7 @@ Examples:
- Here documents are too similar to using echo inside of a pipeline.
- Subshells, command substitution and process substitution are strongly related. `fish` only supports command substitution, the others can be achieved either using a block or the psub shellscript function.
- Having both aliases and functions is confusing, especially since both of them have limitations and problems. `fish` functions have none of the drawbacks of either syntax.
- The many Posix quoting styles are silly, especially \$''.
- The many Posix quoting styles are silly, especially $''.
\section sep The law of responsiveness

@ -2,7 +2,7 @@
\subsection echo-synopsis Synopsis
\fish{synopsis}
echo [STRING]
echo [OPTIONS] [STRING]
\endfish
\subsection echo-description Description

@ -1,5 +1,5 @@
/** \page faq Frequently asked questions
/**
\page faq Frequently asked questions
\htmlonly[block]
<div class="fish_left_bar">
<div class="menu faq_menu">

@ -2,7 +2,7 @@
\subsection fish-synopsis Synopsis
\fish{synopsis}
fish [-h] [-v] [-c command] [FILE [ARGUMENTS...]]
fish [OPTIONS] [-c command] [FILE [ARGUMENTS...]]
\endfish
\subsection fish-description Description

@ -2,7 +2,7 @@
\subsection fish_indent-synopsis Synopsis
\fish{synopsis}
fish_indent [options]
fish_indent [OPTIONS]
\endfish
\subsection fish_indent-description Description

@ -25,7 +25,8 @@ A simple prompt:
\fish
function fish_prompt -d "Write out the prompt"
printf '%s@%s%s%s%s> ' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
printf '%s@%s%s%s%s> ' (whoami) (hostname | cut -d . -f 1) \
(set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
end
\endfish

@ -2,7 +2,7 @@
\subsection functions-synopsis Synopsis
\fish{synopsis}
functions [-a|--all] [-n|--names]
functions [-a | --all] [-n | --names]
functions -c OLDNAME NEWNAME
functions -d DESCRIPTION FUNCTION
functions [-eq] FUNCTIONS...

@ -2,8 +2,8 @@
\subsection history-synopsis Synopsis
\fish{synopsis}
history [--save|--clear|--merge]
history [--search|--delete] [--prefix "prefix string"|--contains "search string"]
history (--merge | --save | --clear)
history (--search | --delete) [--prefix "prefix string" | --contains "search string"]
\endfish
\subsection history-description Description
@ -11,9 +11,9 @@ history [--search|--delete] [--prefix "prefix string"|--contains "search string"
`history` is used to list, search and delete the history of commands used.
The following options are available:
- `--merge` immediately incorporates history changes from other sessions. Ordinarily `fish` ignores history changes from sessions started after the current one. This command applies those changes immediately.
- `--save` saves all changes in the history file. The shell automatically saves the history file; this option is provided for internal use.
- `--clear` clears the history file. A prompt is displayed before the history is erased.
- `--merge` immediately incorporates history changes from other sessions. Ordinarily `fish` ignores history changes from sessions started after the current one. This command applies those changes immediately.
- `--search` returns history items in keeping with the `--prefix` or `--contains` options.
- `--delete` deletes history items.
- `--prefix` searches or deletes items in the history that begin with the specified text string.

@ -2,7 +2,10 @@
\subsection if-synopsis Synopsis
\fish{synopsis}
if CONDITION; COMMANDS_TRUE...; [else if CONDITION2; COMMANDS_TRUE2...;] [else; COMMANDS_FALSE...;] end
if CONDITION; COMMANDS_TRUE...;
[else if CONDITION2; COMMANDS_TRUE2...;]
[else; COMMANDS_FALSE...;]
end
\endfish
\subsection if-description Description

@ -1,4 +1,5 @@
/** \mainpage Documentation
/**
\mainpage Documentation
\htmlonly[block]
<div class="fish_left_bar">
<div class="menu docs_menu">
@ -183,7 +184,7 @@ When you start a job in `fish`, `fish` itself will pause, and give control of th
Example:
\fish
emacs &amp;
emacs &
\endfish
will start the emacs text editor in the background.
@ -255,14 +256,14 @@ The other conditionals use the <a href='#variables-status'>exit status</a> of a
This is a short explanation of some of the commonly used words in fish.
- <b>argument</b>, a parameter given to a command
- <b>builtin</b>, a command that is implemented in the shell. Builtins are commands that are so closely tied to the shell that it is impossible to implement them as external commands.
- <b>command</b>, a program that the shell can run.
- <b>function</b>, a block of commands that can be called as if they where a single command. By using functions, it is possible to string together multiple smaller commands into one more advanced command.
- <b>job</b>, a running pipeline or command
- <b>pipeline</b>, a set of commands stringed together so that the output of one command is the input of the next command
- <b>redirection</b>, a operation that changes one of the input/output streams associated with a job
- <b>switch</b>, a special flag sent as an argument to a command that will alter the behavior of the command. A switch almost always begins with one or two hyphens.
- <b>argument</b> a parameter given to a command
- <b>builtin</b> a command that is implemented in the shell. Builtins are commands that are so closely tied to the shell that it is impossible to implement them as external commands.
- <b>command</b> a program that the shell can run.
- <b>function</b> a block of commands that can be called as if they where a single command. By using functions, it is possible to string together multiple smaller commands into one more advanced command.
- <b>job</b> a running pipeline or command
- <b>pipeline</b> a set of commands stringed together so that the output of one command is the input of the next command
- <b>redirection</b> a operation that changes one of the input/output streams associated with a job
- <b>switch</b> a special flag sent as an argument to a command that will alter the behavior of the command. A switch almost always begins with one or two hyphens.
\section docs Help
@ -383,23 +384,27 @@ The exit status of the last run command substitution is available in the <a href
Only part of the output can be used, see <a href='#expand-index-range'>index range expansion</a> for details.
Examples:
\fish
echo (basename image.jpg .jpg).png
# Outputs 'image.png'.
The command `echo (basename image.jpg .jpg).png` will output 'image.png'.
The command `for i in *.jpg; convert $i (basename $i .jpg).png; end` will convert all JPEG files in the current directory to the PNG format using the `convert` program.
for i in *.jpg; convert $i (basename $i .jpg).png; end
# Convert all JPEG files in the current directory to the
# PNG format using the 'convert' program.
\endfish
\subsection expand-brace Brace expansion
A comma separated list of characters enclosed in curly braces will be expanded so each element of the list becomes a new parameter.
Example:
Examples:
\fish
echo input.{c,h,txt} # Outputs 'input.c input.h input.txt'
\endfish
echo input.{c,h,txt}
# Outputs 'input.c input.h input.txt'
The command `mv *.{c,h} src/` moves all files with the suffix '.c' or '.h' to the subdirectory src.
mv *.{c,h} src/
# Moves all files with the suffix '.c' or '.h' to the subdirectory src.
\endfish
\subsection expand-variable Variable expansion
@ -410,12 +415,18 @@ Undefined and empty variables expand to nothing.
To separate a variable name from text it should immediately be followed by, encase the variable within braces.
Examples:
\fish
echo $HOME
# Prints the home directory of the current user.
`echo $HOME` prints the home directory of the current user.
echo $nonexistentvariable
# Prints no output.
`echo $nonexistentvariable` prints no output.
echo The plural of $WORD is {$WORD}s
# Prints "The plural of cat is cats" when $WORD is set to cat.
\endfish
`echo The plural of $WORD is {$WORD}s` prints "The plural of cat is cats" when `$WORD` is set to cat. Note that without the braces, fish will try to expand a variable called `$WORDs`, which may not exist.
Note that without the braces, fish will try to expand a variable called `$WORDs`, which may not exist.
The latter syntax works by exploiting <a href="#expand-brace">brace expansion</a>; care should be taken with array variables and undefined variables, as these behave very differently to POSIX shells.
@ -448,24 +459,19 @@ Some examples:
\fish
# Limit the command substitution output
echo (seq 10)[2..5]
# will use elements from 2 to 5
# Output is:
# 2 3 4 5
# Uses elements from 2 to 5
# Output is: 2 3 4 5
# Use overlapping ranges:
echo (seq 10)[2..5 1..3]
# will take elements from 2 to 5 and then elements from 1 to 3
# Output is:
# 2 3 4 5 1 2 3
# Takes elements from 2 to 5 and then elements from 1 to 3
# Output is: 2 3 4 5 1 2 3
# Reverse output
echo (seq 10)[-1..1]
# will use elements from the last output line to the first one in reverse direction
# Output is:
# 10 9 8 7 6 5 4 3 2 1
# Uses elements from the last output line to
# the first one in reverse direction
# Output is: 10 9 8 7 6 5 4 3 2 1
\endfish
The same works when setting or expanding variables:
@ -591,14 +597,11 @@ end
function avast
set phrase 'Avast, mateys'
# Calling the shiver function here can not
# change any variables in the local scope
shiver
echo $phrase
end
avast
\endfish

@ -2,7 +2,7 @@
\subsection nextd-synopsis Synopsis
\fish{synopsis}
nextd [ -l | --list ] [POS]
nextd [-l | --list] [POS]
\endfish
\subsection nextd-description Description

@ -2,7 +2,7 @@
\subsection psub-synopsis Synopsis
\fish{synopsis}
COMMAND1 (COMMAND2|psub [-f])
COMMAND1 (COMMAND2 | psub [-f])
\endfish
\subsection psub-description Description
@ -24,5 +24,7 @@ process can seek in the stream.
\subsection psub-example Example
`diff (sort a.txt|psub) (sort b.txt|psub)` shows the difference
between the sorted versions of files a.txt and b.txt.
\fish
diff (sort a.txt | psub) (sort b.txt | psub)
# shows the difference between the sorted versions of files `a.txt` and `b.txt`.
\endfish

@ -82,19 +82,21 @@ success, with a non-zero exit status if the commandline was invalid, if the
variable was write-protected or if the variable did not exist.
\subsection set-example Example
`set -xg` will print all global, exported variables.
`set foo hi` sets the value of the variable foo to be hi.
`set -e smurf` removes the variable `smurf`.
`set PATH[4] ~/bin` changes the fourth element of the `PATH` array to `~/bin`
\fish
set -xg
# Prints all global, exported variables.
set foo hi
# Sets the value of the variable $foo to be 'hi'.
set -e smurf
# Removes the variable $smurf
set PATH[4] ~/bin
# Changes the fourth element of the $PATH array to ~/bin
if set python_path (which python)
echo "Python is at $python_path"
end
# Outputs the path to Python if `which` returns true.
\endfish
The above outputs the path to Python if `which` returns true.

@ -2,7 +2,7 @@
\subsection set_color-synopsis Synopsis
\fish{synopsis}
set_color [-h|--help] [-b|--background COLOR] [COLOR]
set_color [OPTIONS] [COLOR]
\endfish
\subsection set_color-description Description

@ -27,6 +27,7 @@ is deprecated in favour of `source`, and `.` will be removed in a future
version of fish.
\subsection source-example Example
`source ~/.config/fish/config.fish` causes fish to re-read its initialization file.
\fish
source ~/.config/fish/config.fish
# Causes fish to re-read its initialization file.
\endfish

@ -40,6 +40,7 @@ The return status is 1 if any `SIGSPEC` is invalid; otherwise trap
returns 0.
\subsection trap-example Example
`trap "status --print-stack-trace" SIGUSR1` prints a stack trace
each time the `SIGUSR1` signal is sent to the shell.
\fish
trap "status --print-stack-trace" SIGUSR1
# Prints a stack trace each time the SIGUSR1 signal is sent to the shell.
\endfish

@ -1,5 +1,5 @@
/** \page tutorial Tutorial
/**
\page tutorial Tutorial
\htmlonly[block]
<div class="fish_left_bar">
<div class="menu tutorial_menu">
@ -23,7 +23,10 @@
- <a href="#tut_functions">Functions</a>
- <a href="#tut_loops">Loops</a>
- <a href="#tut_prompt">Prompt</a>
- <a href="#tut_path">$PATH</a>
- <a href="#tut_startup">Startup</a>
- <a href="#tut_autoload">Autoloading Functions</a>
- <a href="#tut-more">Ready for more?</a>
\htmlonly[block]
</div>
@ -33,7 +36,6 @@
<h1 class="interior_title">fish tutorial</h1>
\endhtmlonly
\section tut_why_fish Why fish?
`fish` is a fully-equipped command line shell (like bash or zsh) that is smart and user-friendly. `fish` supports powerful features like syntax highlighting, autosuggestions, and tab completions that just work, with nothing to learn or configure.
@ -45,14 +47,14 @@ If you want to make your command line more productive, more useful, and more fun
This tutorial assumes a basic understanding of command line shells and Unix commands, and that you have a working copy of `fish`.
If you have a strong understanding of other shells, and want to know what `fish` does differently, search for the magic phrase <i>unlike other shells</i>, which is used to call out important differences.
If you have a strong understanding of other shells, and want to know what `fish` does differently, search for the magic phrase <em>unlike other shells</em>, which is used to call out important differences.
When you start `fish`, you should see this:
\fish{cli-dark}
Welcome to fish, the friendly interactive shell
Type <em>help</em> for instructions on how to use fish
you@hostname <em>~</em>>
<outp>Welcome to fish, the friendly interactive shell</outp>
<outp>Type <span class="cwd">help</span> for instructions on how to use fish</outp>
<asis>you@hostname</asis> ~>___
\endfish
`fish` comes with a default prompt that shows your username, hostname, and working directory. You'll see <a href="#tut_prompt">how to change your prompt</a> further down. From now on, we'll pretend your prompt is just a '`>`' to save space.
@ -63,17 +65,17 @@ you@hostname <em>~</em>>
`fish` runs commands like other shells: you type a command, followed by its arguments. Spaces are separators:
\fish{cli-dark}
> <b>echo</b> <i>hello world</i>
hello world
>_ echo hello world
<outp>hello world</outp>
\endfish
You can include a literal space in an argument with a backslash, or by using single or double quotes:
\fish{cli-dark}
> <b>mkdir</b> <i>My\ Files</i>
> <b>cp</b> <i>~/Some\ File</i> <i class=quote>'My Files'</i>
> <b>ls</b> <i class=quote>"My Files"</i>
Some File
>_ mkdir My\ Files
>_ cp ~/Some\ File 'My Files'
>_ ls "My Files"
<outp>Some File</outp>
\endfish
Commands can be chained with semicolons.
@ -84,9 +86,9 @@ Commands can be chained with semicolons.
`fish` has excellent help and man pages. Run `help` to open help in a web browser, and `man` to open it in a man page. You can also ask for help with a specific command, for example, `help set` to open in a web browser, or `man set` to see it in the terminal.
\fish{cli-dark}
> <b>man</b> <i>set</i>
set - handle shell variables
Synopsis...
>_ man set
<outp>set - handle shell variables</outp>
<outp> Synopsis...</outp>
\endfish
@ -95,19 +97,19 @@ set - handle shell variables
You'll quickly notice that `fish` performs syntax highlighting as you type. Invalid commands are colored red by default:
\fish{cli-dark}
> <error>/bin/mkd</error>
>_ <error>/bin/mkd</error>
\endfish
A command may be invalid because it does not exist, or refers to a file that you cannot execute. When the command becomes valid, it is shown in a different color:
\fish{cli-dark}
> <b>/bin/mkdir</b>
>_ /bin/mkdir
\endfish
`fish` will underline valid file paths as you type them:
\fish{cli-dark}
> <b>cat</b> <i><span style="text-decoration: underline">~/somef<span class="u">i</span></span></i>
>_ cat <u>~/somefi</u>__
\endfish
This tells you that there exists a file that starts with '`somefi`', which is useful feedback as you type.
@ -117,29 +119,29 @@ These colors, and many more, can be changed by running `fish_config`, or by modi
\section tut_wildcards Wildcards
`fish` supports the familiar wildcard *. To list all JPEG files:
`fish` supports the familiar wildcard `*`. To list all JPEG files:
\fish{cli-dark}
> <b>ls</b> <i>*.jpg</i>
lena.jpg
meena.jpg
santa maria.jpg
>_ ls *.jpg
<outp>lena.jpg</outp>
<outp>meena.jpg</outp>
<outp>santa maria.jpg</outp>
\endfish
You can include multiple wildcards:
\fish{cli-dark}
> <b>ls</b> <i>l*.p*</i>
lena.png
lesson.pdf
>_ ls l*.p*
<outp>lena.png</outp>
<outp>lesson.pdf</outp>
\endfish
Especially powerful is the <i>recursive wildcard</i> ** which searches directories recursively:
Especially powerful is the recursive wildcard ** which searches directories recursively:
\fish{cli-dark}
> <b>ls</b> <i>/var/\**.log</i>
/var/log/system.log
/var/run/sntp.log
>_ ls /var/**.log
<outp>/var/log/system.log</outp>
<outp>/var/run/sntp.log</outp>
\endfish
If that directory traversal is taking a long time, you can @key{Control,C} out of it.
@ -150,14 +152,14 @@ If that directory traversal is taking a long time, you can @key{Control,C} out o
You can pipe between commands with the usual vertical bar:
\fish{cli-dark}
> <b>echo</b> <i>hello world</i> | <b>wc</b>
1 2 12
>_ echo hello world | wc
<outp> 1 2 12</outp>
\endfish
stdin and stdout can be redirected via the familiar &lt; and &gt;. Unlike other shells, stderr is redirected with a caret ^
\fish{cli-dark}
> <b>grep</b> <i>fish</i> &lt; /etc/shells > ~/output.txt ^ ~/errors.txt
>_ grep fish < /etc/shells > ~/output.txt ^ ~/errors.txt
\endfish
@ -166,24 +168,23 @@ stdin and stdout can be redirected via the familiar &lt; and &gt;. Unlike other
`fish` suggests commands as you type, and shows the suggestion to the right of the cursor, in gray. For example:
\fish{cli-dark}
> <b class="error">/bin/h</b><span class="suggest"><span class="u">o</span>stname</span>
>_ <error>/bin/h</error><s>__ostname</s>
\endfish
It knows about paths and options:
\fish{cli-dark}
> <b>grep</b> <i>--i<span class="suggest"><span class="u">g</span>nore-case</span></i>
>_ grep --i<s>__gnore-case</s>
\endfish
And history too. Type a command once, and you can re-summon it by just typing a few letters:
\fish{cli-dark}
> <b>r</b><span class="suggest"><span class="u">s</span>ync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo</span>
>_ r<s>__sync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo</s>
\endfish
To accept the autosuggestion, hit right arrow or @key{Control,F}. To accept a single word of the autosuggestion, @key{Alt,&rarr;} (right arrow). If the autosuggestion is not what you want, just ignore it.
\section tut_tab_completions Tab Completions
`fish` comes with a rich set of tab completions, that work "out of the box."
@ -191,14 +192,14 @@ To accept the autosuggestion, hit right arrow or @key{Control,F}. To accept a si
Press tab, and `fish` will attempt to complete the command, argument, or path:
\fish{cli-dark}
> <b class="error">/pri</b><span class="meta">&lt;tab&gt; &rarr;</span> <b>/private/</b>
>_ <error>/pri</error> @key{Tab} &rarr; /private/
\endfish
If there's more than one possibility, it will list them:
\fish{cli-dark}
> <b class="error">~/stuff/s</b><span class="meta">&lt;tab&gt;</span>
<i>~/stuff/s</i>cript.sh <i class="quote">(Executable, 4.8kB)</i> <i>~/stuff/s</i>ources/ <i class="quote">(Directory)</i>
>_ <error>~/stuff/s</error> @key{Tab}
<outp><m>~/stuff/s</m>cript.sh <i>(Executable, 4.8kB)</i> <m>~/stuff/s</m>ources/ <i>(Directory)</i></outp>
\endfish
Hit tab again to cycle through the possibilities.
@ -206,51 +207,50 @@ Hit tab again to cycle through the possibilities.
`fish` can also complete many commands, like git branches:
\fish{cli-dark}
> <b>git</b> <i>merge pr</i><span class="meta">&lt;tab&gt; &rarr;</span> git merge prompt_designer
> <b>git</b> <i>checkout b</i><span class="meta">&lt;tab&gt;</span>
<i>b</i>uiltin_list_io_merge <i class="quote">(Branch)</i> <i>b</i>uiltin_set_color <i class="quote">(Branch)</i> <i>b</i>usted_events <i class="quote">(Tag)</i>
>_ git merge pr @key{Tab} &rarr; git merge prompt_designer
>_ git checkout b @key{Tab}
<outp><m>b</m>uiltin_list_io_merge <i>(Branch)</i> <m>b</m>uiltin_set_color <i>(Branch)</i> <m>b</m>usted_events <i>(Tag)</i></outp>
\endfish
Try hitting tab and see what `fish` can do!
\section tut_variables Variables
Like other shells, a dollar sign performs <i>variable substitution</i>:
Like other shells, a dollar sign performs variable substitution:
\fish{cli-dark}
> <b>echo</b> <i>My home directory is $HOME</i>
My home directory is /home/tutorial
>_ echo My home directory is $HOME
<outp>My home directory is /home/tutorial</outp>
\endfish
Variable substitution also occurs in double quotes, but not single quotes:
\fish{cli-dark}
> <b>echo</b> <i class="quote">"My current directory is </i><i>$</i><i class="quote">PWD"</i>
My current directory is /home/tutorial
> <b>echo</b> <i class="quote">'My current directory is $PWD'</i>
My current directory is $PWD
>_ echo "My current directory is $PWD"
<outp>My current directory is /home/tutorial</outp>
>_ echo 'My current directory is $PWD'
<outp>My current directory is $PWD</outp>
\endfish
Unlike other shells, `fish` has no dedicated syntax for setting variables. Instead it has an ordinary command: `set`, which takes a variable name, and then its value.
\fish{cli-dark}
> <b>set</b> <i>name</i> <i class="quote">'Mister Noodle'</i>
> <b>echo</b> <i>$name</i>
Mister Noodle
>_ set name 'Mister Noodle'
>_ echo $name
<outp>Mister Noodle</outp>
\endfish
(Notice the quotes: without them, `Mister` and `Noodle` would have been separate arguments, and `$name` would have been made into a <i>list</i> of two elements.)
(Notice the quotes: without them, `Mister` and `Noodle` would have been separate arguments, and `$name` would have been made into a list of two elements.)
Unlike other shells, variables are <i>not</i> further split after substitution:
Unlike other shells, variables are not further split after substitution:
\fish{cli-dark}
> <b>mkdir</b> <i>$name</i>
> <b>ls</b>
Mister Noodle
>_ mkdir $name
>_ ls
<outp>Mister Noodle</outp>
\endfish
In bash, this would have created two directories "Mister" and "Noodle". In `fish`, it created only one: the variable had the value "Mister Noodle", so that is the argument that was passed to <span style="mono">mkdir</span>, spaces and all.
In bash, this would have created two directories "Mister" and "Noodle". In `fish`, it created only one: the variable had the value "Mister Noodle", so that is the argument that was passed to `mkdir`, spaces and all.
\section tut_exit_status Exit Status
@ -258,43 +258,44 @@ In bash, this would have created two directories "Mister" and "Noodle". In `fish
Unlike other shells, `fish` stores the exit status of the last command in `$status` instead of `$?`.
\fish{cli-dark}
> <b>false</b>
> <b>echo</b> <i>$status</i>
1
>_ false
>_ echo $status
<outp>1</outp>
\endfish
Zero is considered success, and non-zero is failure.
<h2 id="tut_exports">Exports (Shell Variables)</h2>
\section tut_exports Exports (Shell Variables)
Unlike other shells, `fish` does not have an export command. Instead, a variable is exported via an option to `set`, either `--export` or just `-x`.
\fish{cli-dark}
> <b>set</b> <i>-x MyVariable SomeValue</i>
> <b>env</b> | <b>grep</b> <i>MyVariable</i>
<span style="background: #A0A">MyVariable</span>=SomeValue
>_ set -x MyVariable SomeValue
>_ env | grep MyVariable
<outp><sm>MyVariable</sm>=SomeValue</outp>
\endfish
You can erase a variable with `-e` or `--erase`
\fish{cli-dark}
> <b>set</b> <i>-e MyVariable</i>
> <b>env</b> | <b>grep</b> <i>MyVariable</i>
<span class="meta">(no output)</span>
>_ set -e MyVariable
>_ env | grep MyVariable
<outp>(no output)</outp>
\endfish
\section tut_lists Lists
The `set` command above used quotes to ensure that `Mister Noodle` was one argument. If it had been two arguments, then `name` would have been a <i>list</i> of length 2. In fact, all variables in `fish` are really lists, that can contain any number of values, or none at all.
The `set` command above used quotes to ensure that `Mister Noodle` was one argument. If it had been two arguments, then `name` would have been a list of length 2. In fact, all variables in `fish` are really lists, that can contain any number of values, or none at all.
Some variables, like `$PWD`, only have one value. By convention, we talk about that variable's value, but we really mean its <i>first</i> (and only) value.
Some variables, like `$PWD`, only have one value. By convention, we talk about that variable's value, but we really mean its first (and only) value.
Other variables, like `$PATH`, really do have multiple values. During <i>variable expansion</i>, the variable expands to become multiple arguments:
Other variables, like `$PATH`, really do have multiple values. During variable expansion, the variable expands to become multiple arguments:
\fish{cli-dark}
> <b>echo</b> <i>$PATH</i>
/usr/bin /bin /usr/sbin /sbin /usr/local/bin
>_ echo $PATH
<outp>/usr/bin /bin /usr/sbin /sbin /usr/local/bin</outp>
\endfish
Lists cannot contain other lists: there is no recursion. A variable is a list of strings, full stop.
@ -302,48 +303,48 @@ Lists cannot contain other lists: there is no recursion. A variable is a list o
Get the length of a list with `count`:
\fish{cli-dark}
> <b>count</b> <i>$PATH</i>
5
>_ count $PATH
<outp>5</outp>
\endfish
You can append (or prepend) to a list by setting the list to itself, with some additional arguments. Here we append /usr/local/bin to $PATH:
\fish{cli-dark}
> <b>set</b> <i>PATH $PATH /usr/local/bin</i>
>_ set PATH $PATH /usr/local/bin
\endfish
You can access individual elements with square brackets. Indexing starts at 1 from the beginning, and -1 from the end:
\fish{cli-dark}
> <b>echo</b> <i>$PATH</i>
/usr/bin /bin /usr/sbin /sbin /usr/local/bin
> <b>echo</b> <i>$PATH[1]</i>
/usr/bin
> <b>echo</b> <i>$PATH[-1]</i>
/usr/local/bin
>_ echo $PATH
<outp>/usr/bin /bin /usr/sbin /sbin /usr/local/bin</outp>
>_ echo $PATH[1]
<outp>/usr/bin</outp>
>_ echo $PATH[-1]
<outp>/usr/local/bin</outp>
\endfish
You can also access ranges of elements, known as "slices:"
\fish{cli-dark}
> <b>echo</b> <i>$PATH[1..2]</i>
/usr/bin /bin
> <b>echo</b> <i>$PATH[-1..2]</i>
/usr/local/bin /sbin /usr/sbin /bin
>_ echo $PATH[1..2]
<outp>/usr/bin /bin</outp>
>_ echo $PATH[-1..2]
<outp>/usr/local/bin /sbin /usr/sbin /bin</outp>
\endfish
You can iterate over a list (or a slice) with a <i>for loop</i>:
You can iterate over a list (or a slice) with a for loop:
\fish{cli-dark}
> <b>for</b> <i>val</i> <b>in</b> <i>$PATH</i>
<b>echo</b> <i>"entry: $val"</i>
<b>end</b>
entry: /usr/bin/
entry: /bin
entry: /usr/sbin
entry: /sbin
entry: /usr/local/bin
>_ for val in $PATH
echo "entry: $val"
end
<outp>entry: /usr/bin/</outp>
<outp>entry: /bin</outp>
<outp>entry: /usr/sbin</outp>
<outp>entry: /sbin</outp>
<outp>entry: /usr/local/bin</outp>
\endfish
@ -352,62 +353,64 @@ entry: /usr/local/bin
Command substitutions use the output of one command as an argument to another. Unlike other shells, `fish` does not use backticks ` for command substitutions. Instead, it uses parentheses:
\fish{cli-dark}
> <b>echo</b> <i>In (</i><b>pwd</b><i>), running (</i><b>uname</b><i>)</i>
In /home/tutorial, running FreeBSD
>_ echo In (pwd), running (uname)
<outp>In /home/tutorial, running FreeBSD</outp>
\endfish
A common idiom is to capture the output of a command in a variable:
\fish{cli-dark}
> <b>set</b> <i>os (</i><b>uname</b><i>)</i>
> <b>echo</b> <i>$os</i>
Linux
>_ set os (uname)
>_ echo $os
<outp>Linux</outp>
\endfish
Command substitutions are not expanded within quotes. Instead, you can temporarily close the quotes, add the command substitution, and reopen them, all in the same argument:
\fish{cli-dark}
> <b>touch</b> <i class="quote">"testing_"</i><i>(</i><b>date</b> <i>+%s</i><i>)</i><i class="quote">".txt"</i>
> <b>ls</b> <i>*.txt</i>
testing_1360099791.txt
>_ touch <i class="quote">"testing_"</i>(date +%s)<i class="quote">".txt"</i>
>_ ls *.txt
<outp>testing_1360099791.txt</outp>
\endfish
<h2 id="tut_combiners">Combiners (And, Or, Not)</h2>
\section tut_combiners Combiners (And, Or, Not)
Unlike other shells, `fish` does not have special syntax like &amp;&amp; or || to combine commands. Instead it has commands `and`, `or`, and `not`.
\fish{cli-dark}
> <b>cp</b> <i>file1.txt file1_bak.txt</i>; <b>and echo</b> <i class="quote">"Backup successful"</i>; <b>or echo</b> <i class="quote">"Backup failed"</i>
Backup failed
>_ cp file1.txt file1_bak.txt; and echo "Backup successful"; or echo "Backup failed"
<outp>Backup failed</outp>
\endfish
<h2 id="tut_conditionals">Conditionals (If, Else, Switch)</h2>
\section tut_conditionals Conditionals (If, Else, Switch)
Use `if`, `else if`, and `else` to conditionally execute code, based on the exit status of a command.
\fish{cli-dark}
<b>if grep</b> <i>fish /etc/shells</i>
<b>echo</b> <i>Found fish</i>
<b>else if grep</b> <i>bash /etc/shells</i>
<b>echo</b> <i>Found bash</i>
<b>else</b>
<b>echo</b> <i>Got nothing</i>
<b>end</b>
if grep fish /etc/shells
echo Found fish
else if grep bash /etc/shells
echo Found bash
else
echo Got nothing
end
\endfish
There is also a `switch` command:
\fish{cli-dark}
<b>switch</b> <i>(</i><b>uname</b><i>)</i>
<b>case</b> <i>Linux</i>
<b>echo</b> <i>Hi Tux!</i>
<b>case</b> <i>Darwin</i>
<b>echo</b> <i>Hi Hexley!</i>
<b>case</b> <i>FreeBSD NetBSD DragonFly</i>
<b>echo</b> <i>Hi Beastie!</i>
<b>case</b> <i class="quote">'*'</i>
<b>echo</b> <i>Hi, stranger!</i>
<b>end</b>
switch (uname)
case Linux
echo Hi Tux!
case Darwin
echo Hi Hexley!
case FreeBSD NetBSD DragonFly
echo Hi Beastie!
case '*'
echo Hi, stranger!
end
\endfish
Note that `case` does not fall through, and can accept multiple arguments or (quoted) wildcards.
@ -418,13 +421,13 @@ Note that `case` does not fall through, and can accept multiple arguments or (qu
A `fish` function is a list of commands, which may optionally take arguments. Unlike other shells, arguments are not passed in "numbered variables" like `$1`, but instead in a single list `$argv`. To create a function, use the `function` builtin:
\fish{cli-dark}
> <i><b>function</b> say_hello
<b>echo</b> Hello $argv
<b>end</b></i>
> <b>say_hello</b>
Hello
> <b>say_hello <i>everybody!</i></b>
Hello everybody!
>_ function say_hello
echo Hello $argv
end
>_ say_hello
<outp>Hello</outp>
>_ say_hello everybody!
<outp>Hello everybody!</outp>
\endfish
Unlike other shells, `fish` does not have aliases or special prompt syntax. Functions take their place.
@ -432,14 +435,14 @@ Unlike other shells, `fish` does not have aliases or special prompt syntax. Func
You can list the names of all functions with the `functions` keyword (note the plural!). `fish` starts out with a number of functions:
\fish{cli-dark}
> <b>functions</b>
alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, sgrep, trap, type, umask, up-or-search, vared
>_ functions
<outp>alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, sgrep, trap, type, umask, up-or-search, vared</outp>
\endfish
You can see the source for any function by passing its name to `functions`:
\fish{cli-dark}
> <b>functions</b> <i>ls</i>
>_ functions ls
function ls --description 'List contents of directory'
command ls -G $argv
end
@ -451,29 +454,29 @@ end
While loops:
\fish{cli-dark}
> <b>while</b> <i>true</i>
<b>echo</b> <i class="quote">"Loop forever"</i>
<b>end</b>
Loop forever
Loop forever
Loop forever
...
>_ while true
echo <i class="quote">"Loop forever"</i>
end
<outp>Loop forever</outp>
<outp>Loop forever</outp>
<outp>Loop forever</outp>
<outp>...</outp>
\endfish
For loops can be used to iterate over a list. For example, a list of files:
\fish{cli-dark}
> <b>for</b> <i>file in *.txt</i>
<b>cp</b> <i>$file $file.bak</i>
<b>end</b>
>_ for file in *.txt
cp $file $file.bak
end
\endfish
Iterating over a list of numbers can be done with `seq`:
\fish{cli-dark}
> <b>for</b> <i>x in (</i><b>seq</b> <i>5)</i>
<b>touch</b> <i>file_$x.txt</i>
<b>end</b>
>_ for x in (seq 5)
touch file_$x.txt
end
\endfish
@ -484,48 +487,49 @@ Unlike other shells, there is no prompt variable like PS1. To display your promp
You can define your own prompt:
\fish{cli-dark}
> <b>function</b> <i>fish_prompt</i>
echo <i>"New Prompt % "</i>
<b>end</b>
New Prompt % <span class="u"> </span>
>_ function fish_prompt
echo "New Prompt % "
end
New Prompt % __
\endfish
Multiple lines are OK. Colors can be set via `set_color`, passing it named ANSI colors, or hex RGB values:
\fish{cli-dark}
> <b>function</b> <i>fish_prompt</i>
<b>set_color</b> <i>purple</i>
<b>date</b> <i class="quote">"+%m/%d/%y"</i>
<b>set_color</b> <i>FF0</i>
<b>echo</b> <i>(</i><b>pwd</b><i>)</i> <i class="quote">'>'</i>
<b>set_color</b> <i>normal</i>
<b>end</b>
>_ function fish_prompt
set_color purple
date "+%m/%d/%y"
set_color FF0
echo (pwd) '>'
set_color normal
end
<span style="color: purple">02/06/13</span>
<span style="color: #FF0">/home/tutorial ></span><span class="u"> </span>
<span style="color: #FF0">/home/tutorial ></span>__
\endfish
You can choose among some sample prompts by running `fish_config prompt`. `fish` also supports RPROMPT through `fish_right_prompt`.
\subsection tut-path $PATH
\section tut-path $PATH
`$PATH` is an environment variable containing the directories in which `fish` searches for commands. Instead of separating entries with a colon, $PATH is a list. You can modify $PATH in a few ways:
-# By modifying the `$fish_user_paths` variable, which is automatically appended to `$PATH`. For example, to permanently add `/usr/local/bin` to your `$PATH`, you could write:
\fish{cli-dark}
> <b>set</b> <i>-U fish_user_paths $fish_user_paths /usr/local/bin</i>
>_ set -U fish_user_paths $fish_user_paths /usr/local/bin
\endfish
-# Directly in config.fish (see below).
<h2 id="tut_startup">Startup (Where's .bashrc?)</h2>
\section tut_startup Startup (Where's .bashrc?)
`fish` starts by executing commands in `~/.config/fish/config.fish`. You can create it if it does not exist.
It is possible to directly create functions and variables in `config.fish` file, using the commands shown above. For example:
\fish{cli-dark}
> <b>cat</b> <i>~/.config/fish/config.fish</i>
>_ cat ~/.config/fish/config.fish
set -x PATH $PATH /sbin/
@ -534,16 +538,16 @@ function ll
end
\endfish
However, it is more common and efficient to use <i>autoloading functions</i> and <i>universal variables</i>.
However, it is more common and efficient to use autoloading functions and universal variables.
\subsection tut-autoload Autoloading Functions
\section tut-autoload Autoloading Functions
When `fish` encounters a command, it attempts to <i>autoload</i> a function for that command, by looking for a file with the name of that command in `~/.config/fish/functions/`.
When `fish` encounters a command, it attempts to autoload a function for that command, by looking for a file with the name of that command in `~/.config/fish/functions/`.
For example, if you wanted to have a function `ll`, you would add a text file `ll.fish` to `~/.config/fish/functions`:
\fish{cli-dark}
> <b>cat</b> <i>~/.config/fish/functions/ll.fish</i>
>_ cat ~/.config/fish/functions/ll.fish
function ll
ls -lh $argv
end
@ -552,30 +556,30 @@ end
This is the preferred way to define your prompt as well:
\fish{cli-dark}
> <b>cat</b> <i>~/.config/fish/functions/fish_prompt.fish</i>
>_ cat ~/.config/fish/functions/fish_prompt.fish
function fish_prompt
echo (pwd) '> '
echo (pwd) "> "
end
\endfish
See the documentation for <a href="commands.html#funced">funced</a> and <a href="commands.html#funcsave">funcsave</a> for ways to create these files automatically.
\subsection tut-universal Universal Variables
\section tut-universal Universal Variables
A universal variable is a variable whose value is shared across all instances of `fish`, now and in the future - even after a reboot. You can make a variable universal with `set -U`:
\fish{cli-dark}
> <b>set</b> <i>-U EDITOR vim</i>
>_ set -U EDITOR vim
\endfish
Now in another shell:
\fish{cli-dark}
> <b>echo</b> <i>$EDITOR</i>
>_ echo $EDITOR
vim
\endfish
\subsection tut-more Ready for more?
\section tut-more Ready for more?
If you want to learn more about fish, there is <a href="index.html">lots of detailed documentation</a>, an <a href="https://lists.sourceforge.net/lists/listinfo/fish-users">official mailing list</a>, the IRC channel \#fish on `irc.oftc.net`, and the <a href="http://github.com/fish-shell/fish-shell/">github page</a>.

@ -22,5 +22,7 @@ The following options are available:
and 1 if it could not be found.
\subsection type-example Example
`type fg` outputs the string '`fg is a shell builtin`'.
\fish
type fg
# Outputs the string 'fg is a shell builtin'.
\endfish

@ -129,6 +129,9 @@ h3 {
padding-bottom: 10px;
border-bottom: 1px solid #AAA;
}
em {
font-style: normal;
}
/* Special Formmating */
/* Keyboard */
.key span {
@ -136,7 +139,6 @@ h3 {
}
.key em {
margin-right: 2px;
font-style: normal;
}
.key em, .key b {
padding: 0 4px;
@ -150,7 +152,7 @@ h3 {
tt, code, pre, .fish {
font-family: "DejaVu Sans Mono", Menlo, Monaco, "Source Code Pro", "Ubuntu Mono", "Consolas", "Lucida Console", monospace, fixed;
font-weight: 500;
text-shadow: 0 0 0 rgba(0,0,0,1); /* Stronger anti-aliasing */
text-shadow: 0 0 0 rgba(0,0,0,0.2);
}
code, pre, .line {
white-space: -moz-pre-wrap;
@ -167,19 +169,26 @@ h1 > code, h2 > code, h3 > code {
.fish {
margin: 1rem 0;
padding: 0.6rem 1rem;
font-size: 1.3rem;
line-height: 1.9rem;
color: #333;
font-size: 1.2rem;
line-height: 1.8rem;
color: #111;
text-shadow: 0 0 0 #000; /* Stronger anti-aliasing */
background-color: #fafafa;
/*color: #00afff;*/
/*background-color: #111;*/
border: 1px solid #eee;
border-radius: 0.6rem;
}
.comment { color: #555; }
.command, .function, .binary { color: #23326b; }
/*.command { color: #00F; }*/
/*.binary { color: #F0F; }*/
/*.function { color: #0FF; }*/
.string { color: #725000; }
.variable { color: #741ba3; }
/*.path { color: #F00; }*/
/*.file { color: #0F0; }*/
/*.argument { color: #19c9ff; }*/
/*.comment { color: #c33; }
.command, .function, .binary { color: #2568e2; }
@ -199,32 +208,38 @@ h1 > code, h2 > code, h3 > code {
.synopsis {
border: none;
color: #333;
background-color: #fafafa;
/*color: #00afff;*/
/*background-color: #111;*/
text-shadow: 0 0 0 rgba(0,0,0,0.2);
background: none;
font-size: 1.3rem;
padding: 0;
}
/* Console variants */
.cli-dark {
background-color: #111;
color: #00afff;
padding: 0.4rem 1rem;
border-radius: 0.4rem;
background-color: #222;
color: #ccc;
text-shadow: 0 0 0 #222;
padding: 0.6rem 1.2rem;
border-radius: 0.6rem;
}
.cli-dark .comment { color: #c33; }
.cli-dark .command, .cli-dark .function, .cli-dark .binary { color: #2568e2; }
.cli-dark .command, .cli-dark .function, .cli-dark .binary { color: #2d5ddb; }
.cli-dark .argument, .cli-dark .variable, .cli-dark .path, .cli-dark .file { color: #00afff; }
.cli-dark .redirect { color: #fff; }
.cli-dark .operator, .cli-dark .match, .cli-dark .history { color: #2ff; }
.cli-dark .string { color: #c07d2f; }
.cli-dark .suggest { color: #555; }
.cli-dark .error { color: #f33; font-weight: bold; }
.cli-dark .suggest, .cli-dark em { color: #777; }
.cli-dark .match { color: #2ff; }
.cli-dark .search_match { background-color: #f2f; }
.cli-dark .cwd { color: #2f2; }
.cli-dark .prompt { color: #fff; }
.cli-dark .cursor { border-bottom: 2px solid #ccc; }
.cli-dark .underline { text-decoration: underline; }
.cli-dark .search_match { background-color: #a100a3; }
.cli-dark .cwd, .cli-dark .prompt .path { color: #2f2; }
.cli-dark .prompt { color: #999; }
.cli-dark .cursor { border-bottom: 2px solid #3F3; }
.cli-dark .underline { color: #00afff; text-decoration: underline; }
.cli-dark .error, .cli-dark .error .path { color: #f33; font-weight: bold; }
.cli-dark .key em, .cli-dark .key b {
background-color: #ccc;
border: 1px solid #333;
color: #000;
}
/*Menus*/
.menu { margin: 1.4rem 0; line-height: 2.2rem; }

@ -18,6 +18,7 @@ complex control can be achieved with `while true` containing a
\subsection while-example Example
`while test -f foo.txt; echo file exists; sleep 10; end`
outputs 'file exists' at 10 second intervals as long as
the file foo.txt exists.
\fish
while test -f foo.txt; echo file exists; sleep 10; end
# outputs 'file exists' at 10 second intervals as long as the file foo.txt exists.
\endfish

@ -50,14 +50,18 @@
/^\\fish{[^}]*}$/b
# Then if it's inline. Remove and process immediately...
/^\\fish.*$/ {
# Catch @ symbol
s/@/(at)/
s/^\\fish//
s/\\endfish//
b process
b html
}
# Output blank lines
/^$/b
# Inside \fish block. Process...
/\\endfish/!{
# Catch @ symbol
s/@/((d))/
# Preprocess HTML and HTML-like formatting
/<[^>]*>/ {
b html
@ -79,53 +83,61 @@ b
s|<span style=['"]\([^'"][^'"]*\)">|@span{\1,|
s|<span class=['"]\([^'"][^'"]*\)">|@spcl{\1,|
s|</span>|}|
t html
#.
# Bold
s|<b>|@bold{|
s|<b [^>]*>|@bold{|
s|</b>|}|
#.
# Strong
# Strong (synonimous with emphasis)
s|<strong>|@bold{|
s|<strong [^>]*>|@bold{|
s|</strong>|}|
#.
# Italic
s|<i>|@emph{|
s|<i [^>]*>|@emph{|
s|</i>|}|
#.
# Emphasis
# EMPHasis
s|<em>|@emph{|
s|<em [^>]*>|@emph{|
s|</em>|}|
#.
# Underline
# Italic (synonimous with emphasis)
s|<i>|@emph{|
s|<i [^>]*>|@emph{|
s|</i>|}|
#.
# UNDeRline
s|<u>|@undr{|
s|<u [^>]*>|@undr{|
s|</u>|}|
t html
#.
# Some handy non-standard extensions
# Autosuggestion
# autoSuGgeSTion
s|<s>|@sgst{|
s|<s [^>]*>|@sgst{|
s|</s>|}|
#.
# Error
# MaTCH
s|<m>|@mtch{|
s|<m [^>]*>|@mtch{|
s|</m>|}|
#.
# SearchMaTCh
s|<sm>|@smtc{|
s|<sm [^>]*>|@smtc{|
s|</sm>|}|
#.
# ERrOR
s|<error>|@eror{|
s|<error [^>]*>|@eror{|
s|</error>|}|
#.
# File declaration
s|<file>|@fsfo{|
s|<file [^>]*>|@fsfo{|
s|</file>|}|
#.
# AsIs - protect from auto-formatting
s|<asis>|@asis{|
s|</asis>|}|
#.
# OUTPut - protect from auto-formatting
s|<outp>|@outp{|
s|</outp>|}|
t html
#.
# Clean other unhandled html
@ -134,18 +146,24 @@ t html
#.
# Start processing entities
:process
#.
# Output:
# Line marked as output pass through
/@outp/ {
b
}
# Comments:
# Capture full line comments
/^ *#.*$/ {
/^\( *\)#\(.*\)$/ {
# Assume any line starting with a # is complete
s//@blah{&}/
s//\1@blah{\2}/
t
}
# Match sub-line comments
s/#\(.*$\)/\\\
/#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]/ ! {
s/#\(.*$\)/\\\
<@blah{#\1}\
/
}
#.
# Protected entities These shouldn't allow nested structure, so we move them
# to a marked, new line for a future extract/process/insert action.
@ -155,6 +173,11 @@ s/@asis{\(.*\)}/\\\
<@asis{\1}\
/g
#.
# Manual <span>
s/@span{\(.*\)}/\\\
<@span{\1}\
/g
#.
# String Literals
s/"\([^"]*\)"/\\\
<@dblq{\1}\
@ -163,6 +186,11 @@ s/'\([^']*\)'/\\\
<@sglq{\1}\
/g
#.
# AutoSuggestions.
s/@sgst{\([^}]*\)}/\\\
<@sgst{\1}\
/
#.
# Command/Function options
# Short options
s/-\([A-Za-z]\)\([^A-Za-z}]\)/\\\
@ -174,41 +202,72 @@ s/--\([A-Za-z][A-Za-z0-9=_-]*\)\([^A-Za-z0-9=_-]*\)/\\\
<@opts{--\1}\
\2/g
#.
# Paths
# Normal Directory
s|\([^/~A-Za-z0-9]\)\([~/][/]*\)\([A-Za-z_0-9./-]*\)|\1\\\
<@path{\2\3}\
|g
# Prompt
s/~>_/\\\
<@prmt{~}\
/
s/^>_/@prmt/
#.
# Cursor
#.
s/__$/@curs/
s/__\(.\)/\\\
<@curs{\1}\
/
#.
# Paths
/\n<@dblq[^}]*[~/]/b protect
/\n<@sglq[^}]*[~/]/b protect
/\n<@span[^}]*[~/]/b protect
#.
# Normal Directory
s|mkdir |mkdir :|
s|\([~/:][/]*[.A-Za-z_0-9/-]*\)\\ |\1=|g
s|\([~/][/]*[.A-Za-z_0-9/=-]*\)|\\\
<@path{\1}\
|g
t protect
s| \(:[/]*[.A-Za-z_0-9/=-]*\)|\\\
<@path{\1}\
|g
t protect
#.
# Dot Relative Directory (no spaces in path)
s| *\(./[A-Za-z_0-9/-]*\)| \\\
<@path{\1}\
|g
b protect
#.
# Tidy up. Merge back 'pure' entities from hold space.
:tidy
#.
# Uncomment the following 2 lines (ss) to log the pattern buffer.
# s/^.*$/PATT: &/w debug-lexicon.log
# s/^PATT: //
s/^.*$/PATT: &/w lexicon.log
s/^PATT: //
#.
# Uncomment the following 4 lines (xssx) to log the hold buffer.
# x
# s/^.*$/HOLD: &/w debug-lexicon.log
# s/^HOLD: //
# x
x
s/^.*$/HOLD: &/w lexicon.log
s/^HOLD: //
x
#.
# Tack the hold space to the end of the pattern buffer.
G
#.
# Uncomment the folowing two lines (ss) to log the buffer join.
# s/^.*$/JOIN: &/w debug-lexicon.log
# s/^JOIN: //
s/^.*$/JOIN: &/w lexicon.log
s/^JOIN: //
#.
# Iterate over alternate lines, matching '<' to '\'
:join
s,\([^\\ ]*\)\\\n\([^<]*\)<\(@[^}]*[}\\]\)[\n]*,\1\3\2,
s,\([^\\ ]*\)\\\n\([^<]*\)<\(@[^}]*[}\\]\),\1\3\2,
t join
# Clean up stray new lines
s/\n//g
#.
# Uncomment the folowing two lines (ss) to log the buffer join.
s/^.*$/PCLN: &/w lexicon.log
s/^PCLN: //
# Clean up special cases
#.
/@blah/{
@ -225,6 +284,13 @@ s/\n//g
s/\(redr{[^}]*\)}\( *\)@path{\([^}]*\)/\1\2\3/
t cleanredr
}
/@sgst/ {
:cleansgst
s/\(sgst{@curs{.}[^@]*\)@cmnd{\([^}]*\)}/\1\2/
s/\(sgst{@curs{.}[^@]*\)@sbin{\([^}]*\)}/\1\2/
s/\(sgst{@curs{.}[^@]*\)@path{\([^}]*\)}/\1\2/
t cleansgst
}
/@fsfo/{
:cleanfsfo
s/\(fsfo{[^@}]*\)@cmnd{\([^}]*\)}/\1\2/
@ -233,84 +299,66 @@ s/\n//g
t cleanfsfo
}
#.
# Restore Paths
/@fsfo/ {
s/\(@fsfo{[^=]*\)=/\1 /
}
/@path/ {
:cleanpath
s/\(@path{[^:]*\):/\1/
s/\(@path{[^=]*\)=/\1\\ /
t cleanpath
s/@path{}//
}
#.
# Finally, restructure to follow Fish's command [arguments] semantics.
# Find the initial command, and change any others to arguments, up to a |, ( or ;
# Assumes that a valid line will start with either a builtin, a function or a binary.
#.
# 'if' and 'for' seem to be special cases
/@cmnd{if}/ {
s//@xcmd\
{if}/
s/@cmnd{else}/@xcmd\
{else}/
s/@cmnd{not}/@xcmd\
{not}/
s/$}@cmnd{status}/$}status/
b nextcmnd
}
/@cmnd{for}/ {
s/@cmnd{for}/@xcmd\
{for}/
s/[[:<:]]in[[:>:]]/@args{in}/
b castargs
#.
# Uncomment the folowing two lines (ss) to log the buffer join.
s/^.*$/PREQ: &/w lexicon.log
s/^PREQ: //
#.
# Find initial commands/functions/binaries
#.
# Store prmt, if present
#.
/@prmt/ {
h
s/^\(@prmt *\).*$/\1/
x
s/^@prmt *//
}
#.
s/^\( *\)@sbin/\1@xbin/
s/\( *[;()] *\)@sbin/\1@xbin/
s/\( *@redr{|} *\)@sbin/\1@xbin/
s/^\( *\)@cmnd/\1@xcmd/
s/\( *[;()] *\)@cmnd/\1@xcmd/
s/\( *@redr{|} *\)@cmnd/\1@xcmd/
s/^\( *\)@func/\1@xfnc/
s/\( *[;()] *\)@func/\1@xfnc/
s/\( *@redr{|} *\)@func/\1@xfnc/
s/@cmnd/@args/g
s/@func/@args/g
s/@sbin/@args/g
s/^.*$/PSTQ: &/w lexicon.log
s/^PSTQ: //
#.
# Find initial command
#.
s/^\( *\)@cmnd\(.*\)/\1@xcmd\
\2/
t castargs
s/^\( *\)@func\(.*\)/\1@xfnc\
\2/
t castargs
s/^\( *\)@sbin\(.*\)/\1@xbin\
\2/
t castargs
:nextcmnd
s/@cmnd\(.*\)$/@xcmd\
\1/
t castargs
s/@func\(.*\)$/@xfnc\
\1/
t castargs
s/@sbin\(.*\)$/@xbin\
\1/
t castargs
b cleancmd
:castargs
s/\n\([^;(]*[;(]\)/\1/
s/\n\([^@]*@redr{|}\)/\1/
t nextcmnd
s/\n\([^@]*\)@cmnd\(.*\)/\1@args\
\2/
t castargs
s/\n\([^@]*\)@func\(.*\)/\1@args\
\2/
t castargs
s/\n\([^@]*\)@sbin\(.*\)/\1@args\
\2/
t castargs
s/\n\([^@]*\)@\(....\)\(.*\)/\1@\2\
\3/
t castargs
:cleancmd
s/xcmd/cmnd/g
s/xfnc/func/g
s/xbin/sbin/g
s/\n//g
#.
# Remove any args after echo
#.
/@cmnd{echo}/ {
s//\
&\
/
:cleanecho
s/\n\([^@]*\)@args{\([^}]*\)}/\1\2/
t cleanecho
s/\n//g
w debug-lexicon.log
x
/^@prmt/ {
G
s/^@prmt \n/@prmt /
}
/^@prmt/ ! {
x
}
#.
# Mark up sesitive character entities.
@ -318,13 +366,19 @@ w debug-lexicon.log
:entities
s/</\&lt;/g
s/>/\&gt;/g
s/((d))/@/g
#.
# Uncomment the folowing two lines (ss) to log the final output, sent to Doxygen.
# s/^.*$/OUT : &/w debug-lexicon.log
# s/^OUT : //
s/^.*$/OUT : &/w lexicon.log
s/^OUT : //
#.
# Lines are reassembled, so branch to end
b
# === Main End ===
#.
#.
# === Subroutines ===
# Branched to when content requires.
#.
# Move protected content to hold space and mark up other entities.
:protect
@ -333,22 +387,34 @@ h
# markup on words that should be left alone.
#.
:patternflush
s/\n<@[^}]*}//
s/\n[}]//
s/\n<@[^}]*[}\\]//
s/\\ [^\\]*$/\\/
t patternflush
s/\n$//
s/\n$//g
#.
# Swap the pattern and hold buffers and remove unmarked lines and extra
# characters. Basically the inverse of the 'patternflush' action, with
# additional trailing characters stripped.
x
s/^ *[^<][^@][^}]*$//
s/^ *[^<][^@][^\\]*[\\ ()]*\n//
:holdflush
s/}[)(\\ ][)(\\ ]*/}/
s/\n[];)|* -][^\\]*[\\]*//
t holdflush
s/\n$//
/^\<@[^}]*$/ ! {
s/[^\<]*//
s/^ *\\\n//
s/[()] \\//
s/\n *\\//
s/^[^\<][^@][^\\]*//
s/\n[]|;) ][^\\]*\\//
s/\n[]|;) a-zA-z0-9-][^\\]*$//
s/\n[]|;)}]\\//
s/\n[]|;)}]\n//
s/\n[]|;)}]$//
s/[()]$//
s/}@curs/}/
s/\n@curs$//
s/\n[^\<@][^\\]*\\//
s/\n[^\<@][^\\]*//
s/^\\//
s/\n$//g
}
#.
# Swap the buffers back.
x
@ -356,24 +422,22 @@ x
# A special case. Tidy up after commands.
# Redirectors
s/\([^{|] *\)|/\1@redr{|}/g
s/\([^{<>^] *\)\([0-9]* *[<>^][<>^]*[a-zA-z0-9._-]*\)/\1@redr{\2}/g
s/\([^{&] *\)&[^a-z]/\1@redr{\&amp;}/g
s/\([^{<>^] *\)\([0-9]* *[<>^][<>^]*[^@][a-zA-Z0-9._-]*\)/\1@redr{\2}/g
s/\\}/}\\/g
#.
# Now we can add in 'unsafe' entities that would be too greedy.
# Declared Variables
#:vars
s/\([$%][$%]*\)\([A-Za-z_0-9][A-Za-z_0-9]*\)/@vars{@optr{\1}\2}/g
#.
# Files
s/\([A-Za-z*][A-Za-z]*\.[a-z0-9][a-z0-9]*\)/@fsfo{\1}/g
s/\([^@]\)\([A-Za-z0-9_-][A-Za-z0-9_-]*\.[a-z0-9*][a-z0-9*]*\)/\1@fsfo{\2}/g
#.
# Fold Files into Paths
s/\(@path{[^}]*\)}@fsfo/\1}@fsfo/
#.
:commands
#.
# Manually add a few commands not harvested from source files.
#.
s,[[:<:]]whoami[[:>:]],@sbin{whoami},g
s,[[:<:]]fishd[[:>:]],@sbin{fishd},g
#.
#### This section is built in the Makefile. Just some formatting examples. #####
#.
# fish commands (cmnd) <- 4 character code that has a Doxygen alias counterpart