From eb894264cfe761c72fc532093634004c1e78be49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Eug=C3=AAnio?= Date: Mon, 1 Aug 2022 21:14:29 -0300 Subject: [PATCH] add fish prompt --- user/fish_prompt.fish | 197 ++++++++++++++++++++++++++++++++++++++++++ user/home.nix | 13 ++- 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 user/fish_prompt.fish diff --git a/user/fish_prompt.fish b/user/fish_prompt.fish new file mode 100644 index 0000000..537aefe --- /dev/null +++ b/user/fish_prompt.fish @@ -0,0 +1,197 @@ +#{{@@ header() @@}} +# __ _ _ +# / _(_)___| |__ +# | |_| / __| '_ \ +# | _| \__ \ | | | +# |_| |_|___/_| |_| + + +# Fine, I'll do it myself +function fish_vi_cursor;end +function fish_mode_prompt;end + + +############################################################ +# Color helpers +############################################################ + +function _fish_prompt_color -a color + # separate line needed for bold normal + set_color $color + set_color --bold + set -e argv[1] + echo -en $argv +end + +alias _fish_prompt_warn "_fish_prompt_color 'yellow'" + +alias _fish_prompt_normal "_fish_prompt_color 'normal'" + +############################################################ +# Git +############################################################ + +function _fish_prompt_git_status -a git_status_s code symbol color + echo $git_status_s | string match -qr "^$code" + and _fish_prompt_color "$color" "$symbol" +end + +function _fish_prompt_git_detached + git symbolic-ref -q HEAD &> /dev/null + or git show --oneline -s | + string match -r '^\w+' +end + +function _fish_prompt_git_remote_branches + git for-each-ref --format='%(refname:short)' refs/remotes +end + +function fish_git_prompt + command -qs git + or return + + set -l here (string replace -r '/\.git(/.*)?$' '' "$PWD") + + test -d "$here" + or return + + pushd "$here" + + ############################################################ + # Check if in a git repo and save branch and status + ############################################################ + + set -l git_branch (git branch --show-current 2> /dev/null);or return + set -l git_detach (_fish_prompt_git_detached) + set -l git_remote_branch (git rev-parse --abbrev-ref (git branch --show-current)@{u} 2> /dev/null) + set -l git_status_s (timeout 1s git status -s | string collect) + + _fish_prompt_normal " on " + + ############################################################ + # Left side represents Index/Filesystem + ############################################################ + + _fish_prompt_git_status "$git_status_s" '.M' '~' 'yellow' # Modified + _fish_prompt_git_status "$git_status_s" '.D' '-' 'red' # Deleted + _fish_prompt_git_status "$git_status_s" '\?\?' '?' 'normal' # Untraked files exist + _fish_prompt_git_status "$git_status_s" 'UU' '!' 'yellow' # Unmerged files exist + + # Print name of branch or checkedout commit + if test -n "$git_detach" + _fish_prompt_warn "$git_detach" + else if test -n "$git_branch" + _fish_prompt_accent "$git_branch" + else + _fish_prompt_warn "init" + end + + # Remote has the current branch + if test -n "$git_remote_branch" + # print a "↑" if ahead of origin + test 0 -ne (git log --oneline "$git_remote_branch"..HEAD -- | wc -l) + and set -l _git_sync_ahead '↑' + + # print a "↓" if behind of origin + test 0 -lt (git log --oneline HEAD.."$git_remote_branch" -- | wc -l) + and set -l _git_sync_behind '↓' + + if set -q _git_sync_ahead _git_sync_behind + _fish_prompt_normal '⇅' + else if set -q _git_sync_ahead + _fish_prompt_normal '↑' + else if set -q _git_sync_behind + _fish_prompt_normal '↓' + end + end + + ############################################################ + # Right side represents WorkTree/Staged + ############################################################ + + _fish_prompt_git_status "$git_status_s" 'A.' '+' 'green' # New file + _fish_prompt_git_status "$git_status_s" 'M.' '~' 'green' # Modified + _fish_prompt_git_status "$git_status_s" 'R.' '→' 'yellow' # Moved + _fish_prompt_git_status "$git_status_s" 'D.' '-' 'red' # Deletion staged + + popd +end + + +############################################################ +# Vi mode indicator +############################################################ + +function fish_vimode_prompt # Not fish_mode_prompt! + + if not test $fish_key_bindings = fish_vi_key_bindings + printf '\e[5 q' # Bar + return + end + + # Set cursor shape + if test $fish_bind_mode = insert + printf '\e[5 q' # Bar + else + printf '\e[1 q' # Block + end + + # Print mode symbol, N for normal, I for insert, etc... + # on most cases first letter of mode name + _fish_prompt_accent ( + switch $fish_bind_mode + case replace_one + printf 'o' + case default + printf 'n' + case '*' + printf (string match -r '^.' $fish_bind_mode ) + end | string upper + )' ' +end + + +############################################################ +# Main prompt +############################################################ + +function fish_prompt + # Save current status as it may be overwritten before usage + set _status $status + + _fish_prompt_accent $USER + _fish_prompt_normal " in " + _fish_prompt_accent (prompt_pwd) + + if test -n "$SSH_TTY" + _fish_prompt_normal " at " + _fish_prompt_accent "$hostname" + end + + fish_git_prompt + + # Line break + echo + + fish_vimode_prompt + + if test $_status -ne 0 + _fish_prompt_warn "$_status " + end + + if test $USER = root + _fish_prompt_normal '# ' + else + _fish_prompt_normal '$ ' + end + + # Reset colors + set_color normal +end + + +# These don't seem to work +# set fish_cursor_default block blink +# set fish_cursor_insert line blink +# set fish_cursor_replace_one underscore blink +# set fish_cursor_visual block diff --git a/user/home.nix b/user/home.nix index 51e76ff..d84a80e 100644 --- a/user/home.nix +++ b/user/home.nix @@ -213,7 +213,18 @@ in { gcc nixfmt ]; - programs.fish.enable = true; + programs.fish = { + enable = true; + interactiveShellInit = '' + set -g __accent_color "${accent.color}" + alias _fish_prompt_accent "_fish_prompt_color '$__accent_color'" + ''; + }; + home.file = { + # ".config/sway/config".source = ./sway; + ".config/fish/conf.d/prompt.fish".source = ./fish_prompt.fish; + }; + programs.helix = { enable = true; package = pkgs.unstable.helix;