From 6241bd8453b4f1da39c0868300f892de92252e88 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 24 Feb 2019 17:13:01 -0800 Subject: [PATCH] Add tutorial to sphinx docs build --- sphinx_doc_src/index.rst | 1 + sphinx_doc_src/tutorial.rst | 699 ++++++++++++++++++++++++++++++++++++ 2 files changed, 700 insertions(+) create mode 100644 sphinx_doc_src/tutorial.rst diff --git a/sphinx_doc_src/index.rst b/sphinx_doc_src/index.rst index e12b046eb..288064aeb 100644 --- a/sphinx_doc_src/index.rst +++ b/sphinx_doc_src/index.rst @@ -519,6 +519,7 @@ Commands :maxdepth: 1 commands + tutorial Autosuggestions diff --git a/sphinx_doc_src/tutorial.rst b/sphinx_doc_src/tutorial.rst new file mode 100644 index 000000000..30b22a29d --- /dev/null +++ b/sphinx_doc_src/tutorial.rst @@ -0,0 +1,699 @@ +.. highlight:: fish + +Tutorial +======== + +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. + +If you want to make your command line more productive, more useful, and more fun, without learning a bunch of arcane syntax and configuration options, then ``fish`` might be just what you're looking for! + + +Getting started +--------------- + +Once installed, just type in ``fish`` into your current shell to try it out! + +You will be greeted by the standard fish prompt, +which means you are all set up and can start using fish:: + + > fish + Welcome to fish, the friendly interactive shell + Type help for instructions on how to use fish + you@hostname ~>____ + + +This prompt that you see above is the ``fish`` default prompt: it shows your username, hostname, and working directory. +- to change this prompt see `how to change your prompt `_ +- to switch to fish permanently see `switch your default shell to fish <#switching-to-fish>`_. + +From now on, we'll pretend your prompt is just a '``>``' to save space. + + +Learning fish +------------- + +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 unlike other shells, which is used to call out important differences. + + +Running Commands +---------------- + +``fish`` runs commands like other shells: you type a command, followed by its arguments. Spaces are separators:: + + >_ echo hello world + hello world + + +You can include a literal space in an argument with a backslash, or by using single or double quotes:: + + >_ mkdir My\ Files + >_ cp ~/Some\ File 'My Files' + >_ ls "My Files" + Some File + + +Commands can be chained with semicolons. + + +Getting Help +------------ + +``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. + + + +:: + + >_ man set + set - handle shell variables + Synopsis... + + + +Syntax Highlighting +------------------- + +You'll quickly notice that ``fish`` performs syntax highlighting as you type. Invalid commands are colored red by default:: + + >_ /bin/mkd + + +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:: + + >_ /bin/mkdir + + +``fish`` will underline valid file paths as you type them:: + + >_ cat ~/somefi___ + + +This tells you that there exists a file that starts with '``somefi``', which is useful feedback as you type. + +These colors, and many more, can be changed by running ``fish_config``, or by modifying variables directly. + + +Wildcards +--------- + +``fish`` supports the familiar wildcard ``*``. To list all JPEG files:: + + >_ ls *.jpg + lena.jpg + meena.jpg + santa maria.jpg + + +You can include multiple wildcards:: + + >_ ls l*.p* + lena.png + lesson.pdf + + +Especially powerful is the recursive wildcard ** which searches directories recursively:: + + >_ ls /var/**.log + /var/log/system.log + /var/run/sntp.log + + +If that directory traversal is taking a long time, you can @key{Control,C} out of it. + + +Pipes and Redirections +---------------------- + +You can pipe between commands with the usual vertical bar:: + + >_ echo hello world | wc + 1 2 12 + + +stdin and stdout can be redirected via the familiar < and >. stderr is redirected with a 2>. + + + +:: + + >_ grep fish < /etc/shells > ~/output.txt 2> ~/errors.txt + + + +Autosuggestions +--------------- + +``fish`` suggests commands as you type, and shows the suggestion to the right of the cursor, in gray. For example:: + + >_ /bin/h___ostname + + +It knows about paths and options:: + + >_ grep --i___gnore-case + + +And history too. Type a command once, and you can re-summon it by just typing a few letters:: + + >_ r<___sync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo + + +To accept the autosuggestion, hit @cursor_key{→,right arrow} or @key{Control,F}. To accept a single word of the autosuggestion, @key{Alt,→} (right arrow). If the autosuggestion is not what you want, just ignore it. + +Tab Completions +--------------- + +``fish`` comes with a rich set of tab completions, that work "out of the box." + +Press @key{Tab}, and ``fish`` will attempt to complete the command, argument, or path:: + + >_ /pri @key{Tab} → /private/ + + +If there's more than one possibility, it will list them:: + + >_ ~/stuff/s @key{Tab} + ~/stuff/script.sh (Executable, 4.8kB) \mtch{~/stuff/sources/ (Directory)} + + +Hit tab again to cycle through the possibilities. + +``fish`` can also complete many commands, like git branches:: + + >_ git merge pr @key{Tab} → git merge prompt_designer + >_ git checkout b @key{Tab} + builtin_list_io_merge (Branch) \mtch{builtin_set_color (Branch) busted_events (Tag)} + + +Try hitting tab and see what ``fish`` can do! + +Variables +--------- + +Like other shells, a dollar sign performs variable substitution:: + + >_ echo My home directory is $HOME + My home directory is /home/tutorial + + +Variable substitution also occurs in double quotes, but not single quotes:: + + >_ echo "My current directory is $PWD" + My current directory is /home/tutorial + >_ echo 'My current directory is $PWD' + My current directory is $PWD + + +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. + + + +:: + + >_ set name 'Mister Noodle' + >_ echo $name + Mister Noodle + + +(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 not further split after substitution:: + + >_ mkdir $name + >_ ls + Mister Noodle + + +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. Other shells use the term "arrays", rather than lists. + + +Exit Status +----------- + +Unlike other shells, ``fish`` stores the exit status of the last command in ``$status`` instead of ``$?``. + + + +:: + + >_ false + >_ echo $status + 1 + + +Zero is considered success, and non-zero is failure. + + +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``. + + + +:: + + >_ set -x MyVariable SomeValue + >_ env | grep MyVariable + MyVariable=SomeValue + + +You can erase a variable with ``-e`` or ``--erase`` + + + +:: + + >_ set -e MyVariable + >_ env | grep MyVariable + (no output) + + + +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 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 first (and only) value. + +Other variables, like ``$PATH``, really do have multiple values. During variable expansion, the variable expands to become multiple arguments:: + + >_ echo $PATH + /usr/bin /bin /usr/sbin /sbin /usr/local/bin + + +Note that there are three environment variables that are automatically split on colons to become lists when fish starts running: ``PATH``, ``CDPATH``, ``MANPATH``. Conversely, they are joined on colons when exported to subcommands. All other environment variables (e.g., ``LD_LIBRARY_PATH``) which have similar semantics are treated as simple strings. + +Lists cannot contain other lists: there is no recursion. A variable is a list of strings, full stop. + +Get the length of a list with ``count``:: + + >_ count $PATH + 5 + + +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:: + + >_ set PATH $PATH /usr/local/bin + + + +You can access individual elements with square brackets. Indexing starts at 1 from the beginning, and -1 from the end:: + + >_ echo $PATH + /usr/bin /bin /usr/sbin /sbin /usr/local/bin + >_ echo $PATH[1] + /usr/bin + >_ echo $PATH[-1] + /usr/local/bin + + +You can also access ranges of elements, known as "slices:" + + + +:: + + >_ echo $PATH[1..2] + /usr/bin /bin + >_ echo $PATH[-1..2] + /usr/local/bin /sbin /usr/sbin /bin + + +You can iterate over a list (or a slice) with a for loop:: + + >_ for val in $PATH + echo "entry: $val" + end + entry: /usr/bin/ + entry: /bin + entry: /usr/sbin + entry: /sbin + entry: /usr/local/bin + + +Lists adjacent to other lists or strings are expanded as cartesian products unless quoted (see Variable expansion):: + + >_ set a 1 2 3 + >_ set 1 a b c + >_ echo $a$1 + 1a 2a 3a 1b 2b 3b 1c 2c 3c + >_ echo $a" banana" + 1 banana 2 banana 3 banana + >_ echo "$a banana" + 1 2 3 banana + + +This is similar to Brace expansion. + +Command Substitutions +--------------------- + +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:: + + >_ echo In (pwd), running (uname) + In /home/tutorial, running FreeBSD + + +A common idiom is to capture the output of a command in a variable:: + + >_ set os (uname) + >_ echo $os + Linux + + +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:: + + >_ touch "testing_"(date +%s)".txt" + >_ ls *.txt + testing_1360099791.txt + + +Unlike other shells, fish does not split command substitutions on any whitespace (like spaces or tabs), only newlines. This can be an issue with commands like ``pkg-config`` that print what is meant to be multiple arguments on a single line. To split it on spaces too, use ``string split``. + + + +:: + + >_ printf '%s\n' (pkg-config --libs gio-2.0) + -lgio-2.0 -lgobject-2.0 -lglib-2.0 + >_ printf '%s\n' (pkg-config --libs gio-2.0 | string split " ") + -lgio-2.0 + -lgobject-2.0 + -lglib-2.0 + + + +Separating Commands (Semicolon) +------------------------------- + +Like other shells, fish allows multiple commands either on separate lines or the same line. + +To write them on the same line, use the semicolon (";"). That means the following two examples are equivalent:: + + echo fish; echo chips + + # or + echo fish + echo chips + + + +Combiners (And, Or, Not) +------------------------ + +fish supports the familiar ``&&`` and ``||`` to combine commands, and ``!`` to negate them:: + + >_ ./configure && make && sudo make install + + +fish also supports ``and``, ``or``, and ``not``. The first two are job modifiers and have lower precedence. Example usage:: + + >_ cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt ; and echo "Backup successful"; or echo "Backup failed" + Backup failed + + +As mentioned in the section on the semicolon, this can also be written in multiple lines, like so:: + + cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt + and echo "Backup successful" + or echo "Backup failed" + + + +Conditionals (If, Else, Switch) +------------------------------- + +Use ``if``, ``else if``, and ``else`` to conditionally execute code, based on the exit status of a command. + + + +:: + + if grep fish /etc/shells + echo Found fish + else if grep bash /etc/shells + echo Found bash + else + echo Got nothing + end + + +To compare strings or numbers or check file properties (whether a file exists or is writeable and such), use test, like + + + +:: + + if test "$fish" = "flounder" + echo FLOUNDER + end + + # or + + if test "$number" -gt 5 + echo $number is greater than five + else + echo $number is five or less + end + + +Combiners can also be used to make more complex conditions, like + + + +:: + + if grep fish /etc/shells; and command -sq fish + echo fish is installed and configured + end + + +For even more complex conditions, use ``begin`` and ``end`` to group parts of them. + +There is also a ``switch`` command:: + + switch (uname) + case Linux + echo Hi Tux! + case Darwin + echo Hi Hexley! + case FreeBSD NetBSD DragonFly + echo Hi Beastie! + case '*' + echo Hi, stranger! + end + + +Note that ``case`` does not fall through, and can accept multiple arguments or (quoted) wildcards. + + +Functions +--------- + +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:: + + >_ function say_hello + echo Hello $argv + end + >_ say_hello + Hello + >_ say_hello everybody! + Hello everybody! + + +Unlike other shells, ``fish`` does not have aliases or special prompt syntax. Functions take their place. + +You can list the names of all functions with the ``functions`` keyword (note the plural!). ``fish`` starts out with a number of functions:: + + >_ functions + 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, trap, type, umask, up-or-search, vared + + +You can see the source for any function by passing its name to ``functions``:: + + >_ functions ls + function ls --description 'List contents of directory' + command ls -G $argv + end + + + +Loops +----- + +While loops:: + + >_ while true + echo "Loop forever" + end + Loop forever + Loop forever + Loop forever + ... + + +For loops can be used to iterate over a list. For example, a list of files:: + + >_ for file in *.txt + cp $file $file.bak + end + + +Iterating over a list of numbers can be done with ``seq``:: + + >_ for x in (seq 5) + touch file_$x.txt + end + + + +Prompt +------ + +Unlike other shells, there is no prompt variable like PS1. To display your prompt, ``fish`` executes a function with the name ``fish_prompt``, and its output is used as the prompt. + +You can define your own prompt:: + + >_ function fish_prompt + echo "New Prompt % " + end + New Prompt % ___ + + +Multiple lines are OK. Colors can be set via ``set_color``, passing it named ANSI colors, or hex RGB values:: + + >_ function fish_prompt + set_color purple + date "+%m/%d/%y" + set_color FF0 + echo (pwd) '>' + set_color normal + end + 02/06/13 + /home/tutorial >___ + + +You can choose among some sample prompts by running ``fish_config prompt``. ``fish`` also supports RPROMPT through ``fish_right_prompt``. + +$PATH +----- + +``$PATH`` is an environment variable containing the directories in which ``fish`` searches for commands. Unlike other shells, $PATH is a [list](#tut_lists), not a colon-delimited string. + +To prepend /usr/local/bin and /usr/sbin to ``$PATH``, you can write:: + + >_ set PATH /usr/local/bin /usr/sbin $PATH + + +To remove /usr/local/bin from ``$PATH``, you can write:: + + >_ set PATH (string match -v /usr/local/bin $PATH) + + +You can do so directly in ``config.fish``, like you might do in other shells with ``.profile``. See [this example](#path_example). + +A faster way is to modify the ``$fish_user_paths`` [universal variable](#tut_universal), which is automatically prepended to ``$PATH``. For example, to permanently add ``/usr/local/bin`` to your ``$PATH``, you could write:: + + >_ set -U fish_user_paths /usr/local/bin $fish_user_paths + + +The advantage is that you don't have to go mucking around in files: just run this once at the command line, and it will affect the current session and all future instances too. (Note: you should NOT add this line to ``config.fish``. If you do, the variable will get longer each time you run fish!) + +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: + + + + +:: + + >_ cat ~/.config/fish/config.fish + + set -x PATH $PATH /sbin/ + + function ll + ls -lh $argv + end + + +However, it is more common and efficient to use autoloading functions and universal variables. + +Autoloading 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``:: + + >_ cat ~/.config/fish/functions/ll.fish + function ll + ls -lh $argv + end + + +This is the preferred way to define your prompt as well:: + + >_ cat ~/.config/fish/functions/fish_prompt.fish + function fish_prompt + echo (pwd) "> " + end + + +See the documentation for funced and funcsave for ways to create these files automatically. + +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``:: + + >_ set -U EDITOR vim + + +Now in another shell:: + + >_ echo $EDITOR + vim + + +.. _switching-to-fish: + +Switching to fish? +------------------ + +If you wish to use fish (or any other shell) as your default shell, +you need to enter your new shell's executable ``/usr/local/bin/fish`` in two places: +- add ``/usr/local/bin/fish`` to ``/etc/shells`` +- change your default shell with ``chsh -s /usr/local/bin/fish`` + +You can use the following commands for this: + +Add the fish shell ``/usr/local/bin/fish`` +to ``/etc/shells`` with:: + + >echo /usr/local/bin/fish | sudo tee -a /etc/shells + + +Change your default shell to fish with:: + + >chsh -s /usr/local/bin/fish + + +(To change it back to another shell, just substitute ``/usr/local/bin/fish`` +with ``/bin/bash``, ``/bin/tcsh`` or ``/bin/zsh`` as appropriate in the steps above.) + + +Ready for more? +--------------- + +If you want to learn more about fish, there is lots of detailed documentation, an official mailing list, the IRC channel \#fish on ``irc.oftc.net``, and the github page.