blob: 803007a576e4375387359a2991c401d1b1c784cc (
plain) (
tree)
|
|
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>fish - Notes</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Notes</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/johannst/notes" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="fish1"><a class="header" href="#fish1">fish(1)</a></h1>
<h2 id="quick-info"><a class="header" href="#quick-info">Quick Info</a></h2>
<p>Fish initialization file <code>~/.config/fish/config.fish</code></p>
<p>Switch between different key bindings:</p>
<ul>
<li><code>fish_default_key_bindings</code> to use default key bindings</li>
<li><code>fish_vi_key_bindings</code> to use vi key bindings</li>
</ul>
<h2 id="variables"><a class="header" href="#variables">Variables</a></h2>
<p>Available scopes</p>
<ul>
<li><code>local</code> variable local to a block</li>
<li><code>global</code> variable global to shell instance</li>
<li><code>universal</code> variable universal to all shell instances + preserved across
shell restart</li>
</ul>
<h3 id="setunset-variables"><a class="header" href="#setunset-variables">Set/Unset Variables</a></h3>
<pre><code class="language-text">set <name> [<values>]
-l local scope
-g global scope
-U universal scope
-e erase variable
-S show verbose info
-x export to ENV
-u unexport from ENV
</code></pre>
<h3 id="special-variables-ref"><a class="header" href="#special-variables-ref">Special Variables <a href="https://fishshell.com/docs/current/language.html#special-variables">ref</a></a></h3>
<pre><code class="language-sh">$status # exit code of last command
$pipestatus # list of exit codes of pipe chain
$fish_pid # pid of parent fish shell ($$ in bash)
$last_pid # pid of last started process ($! in bash)
$CMD_DURATION # runtime of last command in ms
</code></pre>
<h3 id="lists"><a class="header" href="#lists">Lists</a></h3>
<p>In <code>fish</code> all variables are lists (start with index <code>1</code>, but lists can't
contain lists.</p>
<pre><code class="language-sh">set foo a b c d
echo $foo[1] # a
echo $foo[-1] # d
echo $foo[2..3] # b c
echo $foo[1 3] # a c
</code></pre>
<p><code>$</code> can be seen as dereference operator.</p>
<pre><code class="language-sh">set foo a; set a 1337
echo $$foo # outputs 1337
</code></pre>
<p>Cartesian product.</p>
<pre><code class="language-sh">echo file.{h,cc}
# file.h file.cc
echo {a,b}{1,2}
# a1 b1 a2 b2
</code></pre>
<h4 id="path-ref"><a class="header" href="#path-ref"><code>*PATH</code> <a href="https://fishshell.com/docs/current/language.html#path-variables">ref</a></a></h4>
<p>Lists ending with <code>PATH</code> are automatically split at <code>:</code> when used and joined
with <code>:</code> when quoted or exported to the environment.</p>
<pre><code class="language-sh">set -x BLA_PATH a:b:c:d
echo $BLA_PATH # a b c d
echo "$BLA_PATH" # a:b:c:d (quoted)
env | grep BLA_PATH # BLA_PATH=a:b:c:d (env)
set FOO_PATH x y z
echo $FOO_PATH # x y z
echo "$FOO_PATH" # x:y:z
</code></pre>
<h2 id="command-handling"><a class="header" href="#command-handling">Command Handling</a></h2>
<pre><code class="language-sh"># sub-commands are not run in quotes
echo "ls output: "(ls)
</code></pre>
<h3 id="io-redirection"><a class="header" href="#io-redirection">I/O redirection</a></h3>
<pre><code class="language-sh"># 'noclobber', fail if 'log' already exists
echo foo >? log
</code></pre>
<h3 id="process-substitution"><a class="header" href="#process-substitution">Process substitution</a></h3>
<p>Redirect output of multiple processes. Same as <code><(..)</code> in bash.</p>
<pre><code class="language-sh">diff (sort a | psub) (sort b | psub)
</code></pre>
<h2 id="control-flow"><a class="header" href="#control-flow">Control Flow</a></h2>
<h3 id="if--else"><a class="header" href="#if--else"><code>if</code> / <code>else</code></a></h3>
<pre><code class="language-sh">if grep foo bar
# do sth
else if grep foobar bar
# do sth else
else
# do sth else
end
</code></pre>
<h3 id="switch"><a class="header" href="#switch"><code>switch</code></a></h3>
<pre><code class="language-sh">switch (echo foo)
case 'foo*'
# do start with foo
case bar dudel
# do bar and dudel
case '*'
# do else
end
</code></pre>
<h3 id="while-loop"><a class="header" href="#while-loop"><code>while</code> Loop</a></h3>
<pre><code class="language-sh">while true
echo foo
end
</code></pre>
<h3 id="for-loop"><a class="header" href="#for-loop"><code>for</code> Loop</a></h3>
<pre><code class="language-sh">for f in (ls)
echo $f
end
</code></pre>
<h2 id="functions"><a class="header" href="#functions">Functions</a></h2>
<p>Function arguments are passed via <code>$argv</code> list.</p>
<pre><code class="language-sh">function fn_foo
echo $argv
end
</code></pre>
<h3 id="autoloading"><a class="header" href="#autoloading">Autoloading</a></h3>
<p>When running a command fish attempts to autoload a function. The shell looks
for <code><cmd>.fish</code> in the locations defined by <code>$fish_function_path</code> and loads
the function lazily if found.</p>
<p>This is the preferred way over monolithically defining all functions in a
startup script.</p>
<h3 id="helper"><a class="header" href="#helper">Helper</a></h3>
<pre><code class="language-sh">functions # list al functions
functions foo # describe function 'foo'
functions -e foo # erase function 'foo'
funced foo # edit function 'foo'
# '-e vim' to edit in vim
</code></pre>
<h3 id="argument-parsing-and-completion"><a class="header" href="#argument-parsing-and-completion">Argument parsing and completion</a></h3>
<p><code>argparse</code> puts options into variables of name <code>_flag_NAME</code>.</p>
<p>References:</p>
<ul>
<li><a href="https://fishshell.com/docs/current/language.html#argument-handling">Argument Handling</a></li>
<li><a href="https://fishshell.com/docs/current/cmds/argparse.html"><code>argparse</code></a></li>
<li><a href="https://fishshell.com/docs/current/completions.html">Writing your own completions</a></li>
<li><a href="https://fishshell.com/docs/current/cmds/complete.html"><code>complete</code></a></li>
</ul>
<pre><code class="language-sh">function moose --d "my moose fn"
# h/help : short / long option (boolean)
# color : only long option (boolean)
# u/user= : option with required argument, only last specified is taken
# f/file+= : option with required argument, can be specified multiple times
#
argparse h/help color= u/user= f/file=+ -- $argv
or return
if set -ql _flag_help
echo "usage ..."
return 0
end
set -ql _flag_file
and echo "file=$_flag_file | cnt:" (count $_flag_file)
set -ql _flag_color
and echo "color=$_flag_color"
set -ql _flag_user
and echo "user=$_flag_user"
end
# Delete all previous defined completions for 'moose'.
complete -c moose -e
# Don't complete files for command.
complete -c moose --no-files
# Help completion.
# -n specifies a conditions. The completion is only active if the command
# returns 0.
complete -c moose -s h -l help -n "not __fish_contains_opt -s h help" \
--description "Print usage help and exit"
# File completion.
# -F force complete files (overwrite --no-files).
# -r requires argument.
complete -c moose -s f -l file -F -r \
--description "Specify file (can be passed multiple times)"
# Color completion.
# -a options for completion.
# -x short for -r and --no-files (-f)
complete -c moose -x -l color -a "red blue" \
--description "Specify a color."
# User completion.
# -a options for completion. Call a function to generate arguments.
complete -c moose -x -s u -l user -a "(__fish_complete_users)" \
--description "Specify a user"
</code></pre>
<h2 id="prompt"><a class="header" href="#prompt">Prompt</a></h2>
<p>The prompt is defined by the output of the <code>fish_prompt</code> function.</p>
<pre><code class="language-sh">function fish_prompt
set -l cmd_ret
echo "> "(pwd) $cmd_ret" "
end
</code></pre>
<blockquote>
<p>Use <code>set_color</code> to manipulate terminal colors and <code>set_color -c</code> to print the
current colors.</p>
</blockquote>
<h2 id="useful-builtins"><a class="header" href="#useful-builtins">Useful Builtins</a></h2>
<p>List all builtins with <code>builtins -n</code>.</p>
<pre><code class="language-sh"># history
history search <str> # search history for <str>
history merge # merge histories from fish sessions
# list
count $var # count elements in list
contains /bin $PATH # return 0 (true) 1 (false)
contains -i /bin $PATH # additionally print index on stdout
# string
string split SEP STRING
# math
math -b hex 4096 # output dec as hex
math 0x1000 # output hex as dec
math "log2(1024)" # call functions
math -s0 7/3 # integer division (by default float)
# status
status -f # abs path of current file
</code></pre>
<h2 id="keymaps"><a class="header" href="#keymaps">Keymaps</a></h2>
<pre><code class="language-text"> Shift-Tab .............. tab-completion with search
Alt-Up / Alt-Down ...... search history with token under the cursor
Alt-l .................. list content of dir under cursor
Alt-p .................. append '2>&1 | less;' to current cmdline
Alt-Left / Alt - Right . prevd / nextd, walk dir history
</code></pre>
<h2 id="debug"><a class="header" href="#debug">Debug</a></h2>
<pre><code class="language-text"> status print-stack-trace .. prints function stacktrace (can be used in scripts)
breakpoint ................ halt script execution and gives shell (C-d | exit
to continue)
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../shells/bash.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../cli/index.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../shells/bash.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../cli/index.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>
|