Here are some rules/recommendations, tips & ticks for creating a more digustable and maintainable config.fish
file.
Table of contents
Intro
As a long term user of the fish-shell, I’ve recently started trying to keep my config.fish
file more maintainable. Your fish/config.fish
, fish/{functions,completions}/*.fish
files are autoloaded when the shell is started up. An important thing to consider is that functions included in the config.fish
file are treated the exact same as files in the functions
directory. What I have recently started doing to create a more modular config.fish
, is exporting funciton calls into the functions directory
.
Normal config.fish
Here is an example of a valid config.fish
:
# global variables
set -gx EDITOR 'nvim'
set -gx VISUAL 'nvim'
set -gx CWD $HOME
# ...
# abbr
abbr -a -g gw 'git worktree'
abbr -a -g gwa 'git worktree add'
abbr -a -g ga 'git add .'
abbr -a -g gc 'git commit '
# ...
# aliases
alias vim='nvim'
alias vi='nvim'
# ...
# theming
set -gx fish_pager_color_prefix '#815bf5' --bold
set -gx fish_pager_color_completion '#685abc'
set -gx fish_pager_color_secondary_prefix '#685abc'
set -gx fish_pager_color_secondary_completion '#685abc'
set -gx fish_pager_color_secondary_descrition '#685abc'
set -gx fish_pager_color_selected_prefix white
set -gx fish_pager_color_selected_completion white
set -gx fish_pager_color_selected_description white
# ...
# keybinds
function fish_user_keybinds
bind \cr 'ranger; commandline -f repaint'
bind -k nul 'complete'
# ...
end
# variable handlers
function _save_dir --on-variable PWD
status --is-command-substitution;and return
set -gx CWD $PWD
end
Cleaner layout for config.fish
As I’ve become more comfortable with the fish-shell, I’ve found it much more
maintainable to move these blocks into the functions the directory, and just
call them in config.fish
. Especially while using the fish-lsp
, I can now
individually test syntax errors/behavior of blocks, without running into huge
errors when a new shell is spawned.
# variables
set_global_vars
# abbr
set_global_abbr
# aliases
set_global_aliases
# theming
set_global_theme
# ---------
# functions
# keybinds
fish_user_keybinds
# variable handlers
_save_dir
In the above example, each respective block is moved into a function inside my
~/.config/fish/functions/
directory. Then, the function is called in my
config.fish
, significantly shortening my overall config’s length.
While I personally don’t do this everywhere inside my config, I think this approach is much more readable than having huge blocks of similiarly grouped commands. The fish-lsp allows for hovering function definitions, and jumping to definitions.
In my own experience, calling functions inside my config has pushed my understanding of the fish-shell to a much more confident level. It has made testing out features I want to add to my enviornment much easier, and I highly recommened designing your config in the manor I described if you are using it across various machines.
More advanced usage
Fish shell provides the variable $fish_function_path
, which provides a list of
paths to search for functions in. If you want to seperate the functions
autoloaded in your config, from scripts you use normally, you can append
directories to this list variable.
Alternatively, you could also make the functions in your config private. In fish-shell the naming convention of functions that begin with leading underscores is typically how this is achieved. Although, it is important to mention these functions are not actual private, and behave the same as normal functions (i.e. you can still call _my_private_function
from the commandline).
Summary
Move your functions and groupings in your config.fish
to an autoloaded directory in the $fish_function_path
list.