mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 09:39:52 +08:00
docs: Add "Writing your own prompt" doc (#9841)
* docs: Add "Writing your own prompt" doc * Remove a space from the "output" * some teensy adjustments * Address feedback * envvar one more PWD * More html warning
This commit is contained in:
parent
f77dc2451e
commit
c385027eca
|
@ -187,6 +187,7 @@ man_pages = [
|
|||
("interactive", "fish-interactive", "", [author], 1),
|
||||
("relnotes", "fish-releasenotes", "", [author], 1),
|
||||
("completions", "fish-completions", "", [author], 1),
|
||||
("prompt", "fish-prompt-tutorial", "", [author], 1),
|
||||
(
|
||||
"fish_for_bash_users",
|
||||
"fish-for-bash-users",
|
||||
|
|
|
@ -171,6 +171,7 @@ Other help pages
|
|||
fish_for_bash_users
|
||||
tutorial
|
||||
completions
|
||||
prompt
|
||||
design
|
||||
relnotes
|
||||
contributing
|
||||
|
|
172
doc_src/prompt.rst
Normal file
172
doc_src/prompt.rst
Normal file
|
@ -0,0 +1,172 @@
|
|||
Writing your own prompt
|
||||
=======================
|
||||
|
||||
.. only:: builder_man
|
||||
|
||||
.. warning::
|
||||
This document uses formatting to show what a prompt would look like. If you are viewing this in the man page,
|
||||
you probably want to switch to looking at the html version instead. Run ``help custom-prompt`` to view it in a web browser.
|
||||
|
||||
Fish ships a number of prompts that you can view with the :doc:`fish_config <cmds/fish_config>` command, and many users have shared their prompts online.
|
||||
|
||||
However, you can also write your own, or adjust an existing prompt. This is a good way to get used to fish's :doc:`scripting language <language>`.
|
||||
|
||||
Unlike other shells, fish's prompt is built by running a function - :doc:`fish_prompt <cmds/fish_prompt>`. Or, more specifically, three functions:
|
||||
|
||||
- :doc:`fish_prompt <cmds/fish_prompt>`, which is the main prompt function
|
||||
- :doc:`fish_right_prompt <cmds/fish_right_prompt>`, which is shown on the right side of the terminal.
|
||||
- :doc:`fish_mode_prompt <cmds/fish_mode_prompt>`, which is shown if :ref:`vi-mode <vi-mode>` is used.
|
||||
|
||||
These functions are run, and whatever they print is displayed as the prompt (minus one trailing newline).
|
||||
|
||||
Here, we will just be writing a simple fish_prompt.
|
||||
|
||||
Our first prompt
|
||||
----------------
|
||||
|
||||
Let's look at a very simple example::
|
||||
|
||||
function fish_prompt
|
||||
echo $PWD '>'
|
||||
end
|
||||
|
||||
This prints the current working directory (:envvar:`PWD`) and a ``>`` symbol to show where the prompt ends. The ``>`` is :ref:`quoted <quotes>` because otherwise it would signify a :ref:`redirection <redirects>`.
|
||||
|
||||
Because we've used :doc:`echo <cmds/echo>`, it adds spaces between the two so it ends up looking like (assuming ``_`` is your cursor):
|
||||
|
||||
.. role:: white
|
||||
.. parsed-literal::
|
||||
:class: highlight
|
||||
|
||||
:white:`/home/tutorial >`\ _
|
||||
|
||||
Formatting
|
||||
----------
|
||||
|
||||
``echo`` adds spaces between its arguments. If you don't want those, you can use :doc:`string join <cmds/string-join>` like this::
|
||||
|
||||
function fish_prompt
|
||||
string join '' -- $PWD '>'
|
||||
end
|
||||
|
||||
The ``--`` indicates to ``string`` that no options can come after it, in case we extend this with something that can start with a ``-``.
|
||||
|
||||
There are other ways to remove the space, including ``echo -s`` and :doc:`printf <cmds/printf>`.
|
||||
|
||||
Adding colo(u)r
|
||||
---------------
|
||||
|
||||
This prompt is functional, but a bit boring. We could add some color.
|
||||
|
||||
Fortunately, fish offers the :doc:`set_color <cmds/set_color>` command, so you can do::
|
||||
|
||||
echo (set_color red)foo
|
||||
|
||||
``set_color`` can also handle RGB colors like ``set_color 23b455``, and other formatting options including bold and italics.
|
||||
|
||||
So, taking our previous prompt and adding some color::
|
||||
|
||||
function fish_prompt
|
||||
string join '' -- (set_color green) $PWD (set_color normal) '>'
|
||||
end
|
||||
|
||||
A "normal" color tells the terminal to go back to its normal formatting options.
|
||||
|
||||
What ``set_color`` does internally is to print an escape sequence that tells the terminal to change color. So if you see something like::
|
||||
|
||||
echo \e\[31mfoo
|
||||
|
||||
that could just be ``set_color red``.
|
||||
|
||||
Shortening the working directory
|
||||
--------------------------------
|
||||
|
||||
This is fine, but our :envvar:`PWD` can be a bit long, and we are typically only interested in the last few directories. We can shorten this with the :doc:`prompt_pwd <cmds/prompt_pwd>` helper that will give us a shortened working directory::
|
||||
|
||||
function fish_prompt
|
||||
string join '' -- (set_color green) (prompt_pwd) (set_color normal) '>'
|
||||
end
|
||||
|
||||
``prompt_pwd`` takes options to control how much to shorten. For instance, if we want to display the last two directories, we'd use ``prompt_pwd --full-length-dirs 2``::
|
||||
|
||||
function fish_prompt
|
||||
string join '' -- (set_color green) (prompt_pwd --full-length-dirs 2) (set_color normal) '>'
|
||||
end
|
||||
|
||||
With a current directory of "/home/tutorial/Music/Lena Raine/Oneknowing", this would print
|
||||
|
||||
.. role:: green
|
||||
.. parsed-literal::
|
||||
:class: highlight
|
||||
|
||||
:green:`~/M/Lena Raine/Oneknowing`>_
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
One important bit of information that every command returns is the :ref:`status <variables-status>`. This is a whole number from 0 to 255, and usually it is used as an error code - 0 if the command returned successfully, or a number from 1 to 255 if not.
|
||||
|
||||
It's useful to display this in your prompt, but showing it when it's 0 seems kind of wasteful.
|
||||
|
||||
First of all, since every command (except for :doc:`set <cmds/set>`) changes the status, you need to store it for later use as the first thing in your prompt. Use a :ref:`local variable <variables-scope>` so it will be confined to your prompt function::
|
||||
|
||||
set -l last_status $status
|
||||
|
||||
And after that, you can set a string if it not zero::
|
||||
|
||||
# Prompt status only if it's not 0
|
||||
set -l stat
|
||||
if test $last_status -ne 0
|
||||
set stat (set_color red)"[$last_status]"(set_color normal)
|
||||
end
|
||||
|
||||
And to print it, we add it to our ``string join``::
|
||||
|
||||
string join '' -- (set_color green) (prompt_pwd) (set_color normal) $stat '>'
|
||||
|
||||
If ``$last_status`` was 0, ``$stat`` is empty, and so it will simply disappear.
|
||||
|
||||
So our entire prompt is now::
|
||||
|
||||
function fish_prompt
|
||||
set -l last_status $status
|
||||
# Prompt status only if it's not 0
|
||||
set -l stat
|
||||
if test $last_status -ne 0
|
||||
set stat (set_color red)"[$last_status]"(set_color normal)
|
||||
end
|
||||
|
||||
string join '' -- (set_color green) (prompt_pwd) (set_color normal) $stat '>'
|
||||
end
|
||||
|
||||
And it looks like:
|
||||
|
||||
.. role:: green
|
||||
.. role:: red
|
||||
.. parsed-literal::
|
||||
:class: highlight
|
||||
|
||||
:green:`~/M/L/Oneknowing`\ :red:`[1]`>_
|
||||
|
||||
after we run ``false`` (which returns 1).
|
||||
|
||||
Where to go from here?
|
||||
----------------------
|
||||
|
||||
We have now built a simple but working and usable prompt, but of course more can be done.
|
||||
|
||||
- Fish offers more helper functions:
|
||||
- ``prompt_login`` to describe the user/hostname/container or ``prompt_hostname`` to describe just the host
|
||||
- ``fish_is_root_user`` to help with changing the symbol for root.
|
||||
- ``fish_vcs_prompt`` to show version control information (or ``fish_git_prompt`` / ``fish_hg_prompt`` / ``fish_svn_prompt`` to limit it to specific systems)
|
||||
- You can add a right prompt by changing :doc:`fish_right_prompt <cmds/fish_right_prompt>` or a vi-mode prompt by changing :doc:`fish_mode_prompt <cmds/fish_mode_prompt>`.
|
||||
- Some prompts have interesting or advanced features
|
||||
- Add the time when the prompt was printed
|
||||
- Show various integrations like python's venv
|
||||
- Color the parts differently.
|
||||
|
||||
You can look at fish's sample prompts for inspiration. Open up :doc:`fish_config <cmds/fish_config>`, find one you like and pick it. For example::
|
||||
|
||||
fish_config prompt show # <- shows all the sample prompts
|
||||
fish_config prompt choose disco # <- this picks the "disco" prompt for this session
|
||||
funced fish_prompt # <- opens fish_prompt in your editor, and reloads it once the editor exits
|
|
@ -607,6 +607,7 @@ div.documentwrapper {
|
|||
.gray { color: #777 }
|
||||
.purple { color: #551a8b; font-weight: bold; }
|
||||
.red { color: #FF0000; }
|
||||
.green { color: #00FF00; }
|
||||
|
||||
/* Color based on the Name.Function (.nf) class from pygments.css. */
|
||||
.command { color: #005fd7 }
|
||||
|
|
|
@ -149,6 +149,8 @@ function help --description 'Show help for the fish shell'
|
|||
set fish_help_page faq.html
|
||||
case fish-for-bash-users
|
||||
set fish_help_page fish_for_bash_users.html
|
||||
case custom-prompt
|
||||
set fish_help_page prompt.html
|
||||
case $faqpages
|
||||
set fish_help_page "faq.html#$fish_help_item"
|
||||
case $for_bash_pages
|
||||
|
|
Loading…
Reference in New Issue
Block a user