1# ----------------------------------------------------------------------------- 2# Fishshell Samples 3# |- Theme / bobthefish 4# |- Function / funced 5# |- Configuration / config.fish 6# ----------------------------------------------------------------------------- 7 8# name: bobthefish 9# 10# bobthefish is a Powerline-style, Git-aware fish theme optimized for awesome. 11# 12# You will probably need a Powerline-patched font for this to work: 13# 14# https://powerline.readthedocs.org/en/latest/fontpatching.html 15# 16# I recommend picking one of these: 17# 18# https://github.com/Lokaltog/powerline-fonts 19# 20# You can override some default options in your config.fish: 21# 22# set -g theme_display_user yes 23# set -g default_user your_normal_user 24 25set -g __bobthefish_current_bg NONE 26 27# Powerline glyphs 28set __bobthefish_branch_glyph \uE0A0 29set __bobthefish_ln_glyph \uE0A1 30set __bobthefish_padlock_glyph \uE0A2 31set __bobthefish_right_black_arrow_glyph \uE0B0 32set __bobthefish_right_arrow_glyph \uE0B1 33set __bobthefish_left_black_arrow_glyph \uE0B2 34set __bobthefish_left_arrow_glyph \uE0B3 35 36# Additional glyphs 37set __bobthefish_detached_glyph \u27A6 38set __bobthefish_nonzero_exit_glyph '! ' 39set __bobthefish_superuser_glyph '$ ' 40set __bobthefish_bg_job_glyph '% ' 41set __bobthefish_hg_glyph \u263F 42 43# Python glyphs 44set __bobthefish_superscript_glyph \u00B9 \u00B2 \u00B3 45set __bobthefish_virtualenv_glyph \u25F0 46set __bobthefish_pypy_glyph \u1D56 47 48# Colors 49set __bobthefish_lt_green addc10 50set __bobthefish_med_green 189303 51set __bobthefish_dk_green 0c4801 52 53set __bobthefish_lt_red C99 54set __bobthefish_med_red ce000f 55set __bobthefish_dk_red 600 56 57set __bobthefish_slate_blue 255e87 58 59set __bobthefish_lt_orange f6b117 60set __bobthefish_dk_orange 3a2a03 61 62set __bobthefish_dk_grey 333 63set __bobthefish_med_grey 999 64set __bobthefish_lt_grey ccc 65 66set __bobthefish_dk_brown 4d2600 67set __bobthefish_med_brown 803F00 68set __bobthefish_lt_brown BF5E00 69 70set __bobthefish_dk_blue 1E2933 71set __bobthefish_med_blue 275379 72set __bobthefish_lt_blue 326D9E 73 74# =========================== 75# Helper methods 76# =========================== 77 78function __bobthefish_in_git -d 'Check whether pwd is inside a git repo' 79 command which git > /dev/null 2>&1; and command git rev-parse --is-inside-work-tree >/dev/null 2>&1 80end 81 82function __bobthefish_in_hg -d 'Check whether pwd is inside a hg repo' 83 command which hg > /dev/null 2>&1; and command hg stat > /dev/null 2>&1 84end 85 86function __bobthefish_git_branch -d 'Get the current git branch (or commitish)' 87 set -l ref (command git symbolic-ref HEAD 2> /dev/null) 88 if [ $status -gt 0 ] 89 set -l branch (command git show-ref --head -s --abbrev |head -n1 2> /dev/null) 90 set ref "$__bobthefish_detached_glyph $branch" 91 end 92 echo $ref | sed "s-refs/heads/-$__bobthefish_branch_glyph -" 93end 94 95function __bobthefish_hg_branch -d 'Get the current hg branch' 96 set -l branch (hg branch ^/dev/null) 97 set -l book " @ "(hg book | grep \* | cut -d\ -f3) 98 echo "$__bobthefish_branch_glyph $branch$book" 99end 100 101function __bobthefish_pretty_parent -d 'Print a parent directory, shortened to fit the prompt' 102 echo -n (dirname $argv[1]) | sed -e 's|/private||' -e "s|^$HOME|~|" -e 's-/\(\.\{0,1\}[^/]\)\([^/]*\)-/\1-g' -e 's|/$||' 103end 104 105function __bobthefish_git_project_dir -d 'Print the current git project base directory' 106 command git rev-parse --show-toplevel 2>/dev/null 107end 108 109function __bobthefish_hg_project_dir -d 'Print the current hg project base directory' 110 command hg root 2>/dev/null 111end 112 113function __bobthefish_project_pwd -d 'Print the working directory relative to project root' 114 echo "$PWD" | sed -e "s*$argv[1]**g" -e 's*^/**' 115end 116 117 118# =========================== 119# Segment functions 120# =========================== 121 122function __bobthefish_start_segment -d 'Start a prompt segment' 123 set_color -b $argv[1] 124 set_color $argv[2] 125 if [ "$__bobthefish_current_bg" = 'NONE' ] 126 # If there's no background, just start one 127 echo -n ' ' 128 else 129 # If there's already a background... 130 if [ "$argv[1]" = "$__bobthefish_current_bg" ] 131 # and it's the same color, draw a separator 132 echo -n "$__bobthefish_right_arrow_glyph " 133 else 134 # otherwise, draw the end of the previous segment and the start of the next 135 set_color $__bobthefish_current_bg 136 echo -n "$__bobthefish_right_black_arrow_glyph " 137 set_color $argv[2] 138 end 139 end 140 set __bobthefish_current_bg $argv[1] 141end 142 143function __bobthefish_path_segment -d 'Display a shortened form of a directory' 144 if test -w "$argv[1]" 145 __bobthefish_start_segment $__bobthefish_dk_grey $__bobthefish_med_grey 146 else 147 __bobthefish_start_segment $__bobthefish_dk_red $__bobthefish_lt_red 148 end 149 150 set -l directory 151 set -l parent 152 153 switch "$argv[1]" 154 case / 155 set directory '/' 156 case "$HOME" 157 set directory '~' 158 case '*' 159 set parent (__bobthefish_pretty_parent "$argv[1]") 160 set parent "$parent/" 161 set directory (basename "$argv[1]") 162 end 163 164 test "$parent"; and echo -n -s "$parent" 165 set_color fff --bold 166 echo -n "$directory " 167 set_color normal 168end 169 170function __bobthefish_finish_segments -d 'Close open prompt segments' 171 if [ -n $__bobthefish_current_bg -a $__bobthefish_current_bg != 'NONE' ] 172 set_color -b normal 173 set_color $__bobthefish_current_bg 174 echo -n "$__bobthefish_right_black_arrow_glyph " 175 set_color normal 176 end 177 set -g __bobthefish_current_bg NONE 178end 179 180 181# =========================== 182# Theme components 183# =========================== 184 185function __bobthefish_prompt_status -d 'Display symbols for a non zero exit status, root and background jobs' 186 set -l nonzero 187 set -l superuser 188 set -l bg_jobs 189 190 # Last exit was nonzero 191 if [ $status -ne 0 ] 192 set nonzero $__bobthefish_nonzero_exit_glyph 193 end 194 195 # if superuser (uid == 0) 196 set -l uid (id -u $USER) 197 if [ $uid -eq 0 ] 198 set superuser $__bobthefish_superuser_glyph 199 end 200 201 # Jobs display 202 if [ (jobs -l | wc -l) -gt 0 ] 203 set bg_jobs $__bobthefish_bg_job_glyph 204 end 205 206 set -l status_flags "$nonzero$superuser$bg_jobs" 207 208 if test "$nonzero" -o "$superuser" -o "$bg_jobs" 209 __bobthefish_start_segment fff 000 210 if [ "$nonzero" ] 211 set_color $__bobthefish_med_red --bold 212 echo -n $__bobthefish_nonzero_exit_glyph 213 end 214 215 if [ "$superuser" ] 216 set_color $__bobthefish_med_green --bold 217 echo -n $__bobthefish_superuser_glyph 218 end 219 220 if [ "$bg_jobs" ] 221 set_color $__bobthefish_slate_blue --bold 222 echo -n $__bobthefish_bg_job_glyph 223 end 224 225 set_color normal 226 end 227end 228 229function __bobthefish_prompt_user -d 'Display actual user if different from $default_user' 230 if [ "$theme_display_user" = 'yes' ] 231 if [ "$USER" != "$default_user" -o -n "$SSH_CLIENT" ] 232 __bobthefish_start_segment $__bobthefish_lt_grey $__bobthefish_slate_blue 233 echo -n -s (whoami) '@' (hostname | cut -d . -f 1) ' ' 234 end 235 end 236end 237 238function __bobthefish_prompt_hg -d 'Display the actual hg state' 239 set -l dirty (command hg stat; or echo -n '*') 240 241 set -l flags "$dirty" 242 test "$flags"; and set flags "" 243 244 set -l flag_bg $__bobthefish_lt_green 245 set -l flag_fg $__bobthefish_dk_green 246 if test "$dirty" 247 set flag_bg $__bobthefish_med_red 248 set flag_fg fff 249 end 250 251 __bobthefish_path_segment (__bobthefish_hg_project_dir) 252 253 __bobthefish_start_segment $flag_bg $flag_fg 254 echo -n -s $__bobthefish_hg_glyph ' ' 255 256 __bobthefish_start_segment $flag_bg $flag_fg 257 set_color $flag_fg --bold 258 echo -n -s (__bobthefish_hg_branch) $flags ' ' 259 set_color normal 260 261 set -l project_pwd (__bobthefish_project_pwd (__bobthefish_hg_project_dir)) 262 if test "$project_pwd" 263 if test -w "$PWD" 264 __bobthefish_start_segment 333 999 265 else 266 __bobthefish_start_segment $__bobthefish_med_red $__bobthefish_lt_red 267 end 268 269 echo -n -s $project_pwd ' ' 270 end 271end 272 273# TODO: clean up the fugly $ahead business 274function __bobthefish_prompt_git -d 'Display the actual git state' 275 set -l dirty (command git diff --no-ext-diff --quiet --exit-code; or echo -n '*') 276 set -l staged (command git diff --cached --no-ext-diff --quiet --exit-code; or echo -n '~') 277 set -l stashed (command git rev-parse --verify refs/stash > /dev/null 2>&1; and echo -n '$') 278 set -l ahead (command git branch -v 2> /dev/null | grep -Eo '^\* [^ ]* *[^ ]* *\[[^]]*\]' | grep -Eo '\[[^]]*\]$' | awk 'ORS="";/ahead/ {print "+"} /behind/ {print "-"}' | sed -e 's/+-/±/') 279 280 set -l new (command git ls-files --other --exclude-standard); 281 test "$new"; and set new '…' 282 283 set -l flags "$dirty$staged$stashed$ahead$new" 284 test "$flags"; and set flags " $flags" 285 286 set -l flag_bg $__bobthefish_lt_green 287 set -l flag_fg $__bobthefish_dk_green 288 if test "$dirty" -o "$staged" 289 set flag_bg $__bobthefish_med_red 290 set flag_fg fff 291 else 292 if test "$stashed" 293 set flag_bg $__bobthefish_lt_orange 294 set flag_fg $__bobthefish_dk_orange 295 end 296 end 297 298 __bobthefish_path_segment (__bobthefish_git_project_dir) 299 300 __bobthefish_start_segment $flag_bg $flag_fg 301 set_color $flag_fg --bold 302 echo -n -s (__bobthefish_git_branch) $flags ' ' 303 set_color normal 304 305 set -l project_pwd (__bobthefish_project_pwd (__bobthefish_git_project_dir)) 306 if test "$project_pwd" 307 if test -w "$PWD" 308 __bobthefish_start_segment 333 999 309 else 310 __bobthefish_start_segment $__bobthefish_med_red $__bobthefish_lt_red 311 end 312 313 echo -n -s $project_pwd ' ' 314 end 315end 316 317function __bobthefish_prompt_dir -d 'Display a shortened form of the current directory' 318 __bobthefish_path_segment "$PWD" 319end 320 321function __bobthefish_in_virtualfish_virtualenv 322 set -q VIRTUAL_ENV 323end 324 325function __bobthefish_virtualenv_python_version -d 'Get current python version' 326 switch (readlink (which python)) 327 case python2 328 echo $__bobthefish_superscript_glyph[2] 329 case python3 330 echo $__bobthefish_superscript_glyph[3] 331 case pypy 332 echo $__bobthefish_pypy_glyph 333 end 334end 335 336function __bobthefish_virtualenv -d 'Get the current virtualenv' 337 echo $__bobthefish_virtualenv_glyph(__bobthefish_virtualenv_python_version) (basename "$VIRTUAL_ENV") 338end 339 340function __bobthefish_prompt_virtualfish -d "Display activated virtual environment (only for virtualfish, virtualenv's activate.fish changes prompt by itself)" 341 set flag_bg $__bobthefish_lt_blue 342 set flag_fg $__bobthefish_dk_blue 343 __bobthefish_start_segment $flag_bg $flag_fg 344 set_color $flag_fg --bold 345 echo -n -s (__bobthefish_virtualenv) $flags ' ' 346 set_color normal 347end 348 349 350# =========================== 351# Apply theme 352# =========================== 353 354function fish_prompt -d 'bobthefish, a fish theme optimized for awesome' 355 __bobthefish_prompt_status 356 __bobthefish_prompt_user 357 if __bobthefish_in_virtualfish_virtualenv 358 __bobthefish_prompt_virtualfish 359 end 360 if __bobthefish_in_git # TODO: do this right. 361 __bobthefish_prompt_git # if something is in both git and hg, check the length of 362 else if __bobthefish_in_hg # __bobthefish_git_project_dir vs __bobthefish_hg_project_dir 363 __bobthefish_prompt_hg # and pick the longer of the two. 364 else 365 __bobthefish_prompt_dir 366 end 367 __bobthefish_finish_segments 368end 369 370# ----------------------------------------------------------------------------- 371# funced - edit a function interactively 372# 373# Synopsis 374# 375# funced [OPTIONS] NAME 376# 377# Description 378# 379# funced provides an interface to edit the definition of the function NAME. 380# ----------------------------------------------------------------------------- 381 382function funced --description 'Edit function definition' 383 set -l editor $EDITOR 384 set -l interactive 385 set -l funcname 386 while set -q argv[1] 387 switch $argv[1] 388 case -h --help 389 __fish_print_help funced 390 return 0 391 392 case -e --editor 393 set editor $argv[2] 394 set -e argv[2] 395 396 case -i --interactive 397 set interactive 1 398 399 case -- 400 set funcname $funcname $argv[2] 401 set -e argv[2] 402 403 case '-*' 404 set_color red 405 printf (_ "%s: Unknown option %s\n") funced $argv[1] 406 set_color normal 407 return 1 408 409 case '*' '.*' 410 set funcname $funcname $argv[1] 411 end 412 set -e argv[1] 413 end 414 415 if begin; set -q funcname[2]; or not test "$funcname[1]"; end 416 set_color red 417 _ "funced: You must specify one function name 418" 419 set_color normal 420 return 1 421 end 422 423 set -l init 424 switch $funcname 425 case '-*' 426 set init function -- $funcname\n\nend 427 case '*' 428 set init function $funcname\n\nend 429 end 430 431 # Break editor up to get its first command (i.e. discard flags) 432 if test -n "$editor" 433 set -l editor_cmd 434 eval set editor_cmd $editor 435 if not type -f "$editor_cmd[1]" >/dev/null 436 _ "funced: The value for \$EDITOR '$editor' could not be used because the command '$editor_cmd[1]' could not be found 437 " 438 set editor fish 439 end 440 end 441 442 # If no editor is specified, use fish 443 if test -z "$editor" 444 set editor fish 445 end 446 447 if begin; set -q interactive[1]; or test "$editor" = fish; end 448 set -l IFS 449 if functions -q -- $funcname 450 # Shadow IFS here to avoid array splitting in command substitution 451 set init (functions -- $funcname | fish_indent --no-indent) 452 end 453 454 set -l prompt 'printf "%s%s%s> " (set_color green) '$funcname' (set_color normal)' 455 # Unshadow IFS since the fish_title breaks otherwise 456 set -e IFS 457 if read -p $prompt -c "$init" -s cmd 458 # Shadow IFS _again_ to avoid array splitting in command substitution 459 set -l IFS 460 eval (echo -n $cmd | fish_indent) 461 end 462 return 0 463 end 464 465 set -q TMPDIR; or set -l TMPDIR /tmp 466 set -l tmpname (printf "$TMPDIR/fish_funced_%d_%d.fish" %self (random)) 467 while test -f $tmpname 468 set tmpname (printf "$TMPDIR/fish_funced_%d_%d.fish" %self (random)) 469 end 470 471 if functions -q -- $funcname 472 functions -- $funcname > $tmpname 473 else 474 echo $init > $tmpname 475 end 476 if eval $editor $tmpname 477 . $tmpname 478 end 479 set -l stat $status 480 rm -f $tmpname >/dev/null 481 return $stat 482end 483 484# ----------------------------------------------------------------------------- 485# Main file for fish command completions. This file contains various 486# common helper functions for the command completions. All actual 487# completions are located in the completions subdirectory. 488## ----------------------------------------------------------------------------- 489 490# 491# Set default field separators 492# 493 494set -g IFS \n\ \t 495 496# 497# Set default search paths for completions and shellscript functions 498# unless they already exist 499# 500 501set -l configdir ~/.config 502 503if set -q XDG_CONFIG_HOME 504 set configdir $XDG_CONFIG_HOME 505end 506 507# __fish_datadir, __fish_sysconfdir, __fish_help_dir, __fish_bin_dir 508# are expected to have been set up by read_init from fish.cpp 509 510# Set up function and completion paths. Make sure that the fish 511# default functions/completions are included in the respective path. 512 513if not set -q fish_function_path 514 set fish_function_path $configdir/fish/functions $__fish_sysconfdir/functions $__fish_datadir/functions 515end 516 517if not contains $__fish_datadir/functions $fish_function_path 518 set fish_function_path[-1] $__fish_datadir/functions 519end 520 521if not set -q fish_complete_path 522 set fish_complete_path $configdir/fish/completions $__fish_sysconfdir/completions $__fish_datadir/completions 523end 524 525if not contains $__fish_datadir/completions $fish_complete_path 526 set fish_complete_path[-1] $__fish_datadir/completions 527end 528 529# 530# This is a Solaris-specific test to modify the PATH so that 531# Posix-conformant tools are used by default. It is separate from the 532# other PATH code because this directory needs to be prepended, not 533# appended, since it contains POSIX-compliant replacements for various 534# system utilities. 535# 536 537if test -d /usr/xpg4/bin 538 if not contains /usr/xpg4/bin $PATH 539 set PATH /usr/xpg4/bin $PATH 540 end 541end 542 543# 544# Add a few common directories to path, if they exists. Note that pure 545# console programs like makedep sometimes live in /usr/X11R6/bin, so we 546# want this even for text-only terminals. 547# 548 549set -l path_list /bin /usr/bin /usr/X11R6/bin /usr/local/bin $__fish_bin_dir 550 551# Root should also have the sbin directories in the path 552switch $USER 553 case root 554 set path_list $path_list /sbin /usr/sbin /usr/local/sbin 555end 556 557for i in $path_list 558 if not contains $i $PATH 559 if test -d $i 560 set PATH $PATH $i 561 end 562 end 563end 564 565# 566# Launch debugger on SIGTRAP 567# 568function fish_sigtrap_handler --on-signal TRAP --no-scope-shadowing --description "Signal handler for the TRAP signal. Lanches a debug prompt." 569 breakpoint 570end 571 572# 573# Whenever a prompt is displayed, make sure that interactive 574# mode-specific initializations have been performed. 575# This handler removes itself after it is first called. 576# 577function __fish_on_interactive --on-event fish_prompt 578 __fish_config_interactive 579 functions -e __fish_on_interactive 580end 581