Skip to main content

config.fish

1# Don't show a greeting on startup. In particular, don't show
2# this message:
3#
4# Welcome to fish, the friendly interactive shell
5# Type help for instructions on how to use fish
6#
7set -g -x fish_greeting ''
10# This tells fish to find functions in my "fish_functions" directory.
12# Note that we have to *prepend* the directory in this repo, so we
13# can override the built-in functions. e.g. I want to use the definition
14# of `fish_prompt` from this repo, rather than the default versions
16# See https://fishshell.com/docs/current/language.html#autoloading-functions
18set -x fish_function_path ~/repos/scripts/fish_functions $fish_function_path
21# Prepend any extra directories to my PATH variable.
23# == Why not use `fish_add_path`? ==
25# That function updates a global `fish_user_paths` array in a file which
26# isn't tracked by Git: `~/.config/fish/fish_variables`. That makes it
27# harder to see how/where my PATH is defined.
29# For example, I could have removed the code that adds a directory to
30# my PATH from this repo, but it would persist in the `fish_variables` file.
32# Using my own function means I get a fresh PATH in every shell, and it's
33# only updated by the directives below. All my PATH additions can be
34# tracked in Git.
36function prepend_to_path
37 if test (count $argv) -eq 0
38 echo "Usage: prepend_to_path /path/to/directory"
39 return 1
40 end
42 set --local new_path $argv[1]
44 if test -d $new_path
45 set --export PATH $new_path $PATH
46 end
47end
49prepend_to_path ~/repos/scripts
50prepend_to_path ~/repos/scripts/aws
51prepend_to_path ~/repos/scripts/ci
52prepend_to_path ~/repos/scripts/debug
53prepend_to_path ~/repos/scripts/fs
54prepend_to_path ~/repos/scripts/git
55prepend_to_path ~/repos/scripts/images
56prepend_to_path ~/repos/scripts/installers
57prepend_to_path ~/repos/scripts/macos
58prepend_to_path ~/repos/scripts/python
59prepend_to_path ~/repos/scripts/tailscale
60prepend_to_path ~/repos/scripts/terraform
61prepend_to_path ~/repos/scripts/text
62prepend_to_path ~/repos/scripts/web
64prepend_to_path ~/repos/flapi.sh
66prepend_to_path ~/.local/bin
68# Path for Rust
69prepend_to_path ~/.cargo/bin
71# Path for Python 3
72prepend_to_path /Library/Frameworks/Python.framework/Versions/3.13/bin
74# Paths for Ruby and bundler
75prepend_to_path /opt/homebrew/bin
76prepend_to_path /opt/homebrew/opt/ruby/bin
77prepend_to_path /opt/homebrew/lib/ruby/gems/3.3.0/bin
79# Prepend any Homebrew-related directories to my PATH variable.
80prepend_to_path /opt/homebrew/bin
81prepend_to_path /opt/homebrew/opt/ruby/bin
83# Path for Go binaries
84prepend_to_path ~/go/bin
87# This prevents me from installing packages with pip without being
88# in a virtualenv first.
90# This allows me to keep my system Python clean, and install all my
91# packages inside virtualenvs.
93# See https://docs.python-guide.org/dev/pip-virtualenv/#requiring-an-active-virtual-environment-for-pip
94# See https://alexwlchan.net/# See https://alexwlchan.net/2023/fish-venv/
96set -g -x PIP_REQUIRE_VIRTUALENV true
99# This points to a file which will be run as a setup script any time
100# I start an interactive Python session. It customises the prompt slightly
101# and adds tab completion.
103# See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONSTARTUP
105set -g -x PYTHONSTARTUP ~/repos/scripts/pythonstartup.py
108# This tells fish to run a couple of functions as event handlers --
109# that is, to run a function when a variable changes or something similar.
110# These functions can't be autoloaded.
112# See https://fishshell.com/docs/current/language.html#event
113# See https://alexwlchan.net/2023/fish-venv/
115function __auto_activate_venv --on-variable PWD --description "Auto activate/deactivate virtualenv when I change directories"
116 auto_activate_venv
117end
120# This updates the Git index whenever I 'cd' into a new directory.
122# Not all directories are Git repos, so if it returns an error, hide it.
124# This is needed for showing my Git branch in my prompt: otherwise I see
125# an asterisk for uncommitted changes until I interact with Git somehow,
126# even though there aren't any.
127function __refresh_git_indexes --on-variable PWD
128 git update-index --refresh >/dev/null 2>&1
129end
132# Load macOS-specific utilities
133if [ (uname -s) = Darwin ]
134 # Get the URL of the frontmost GitHub page and clone it
135 function gh-clone
136 _ensure_ssh_key_loaded
137 github-clone (furl)
138 end
139end
142# These functions run scripts in this repo using the virtualenv, rather
143# than running them with system Python.
145# e.g. emptydir.py relies on the `humanize` library. That isn't installed
146# in my system Python, but it is installed in my `scripts` virtualenv.
148# Useful reading: https://github.com/fish-shell/fish-shell/issues/1776
150function __create_bash_script_alias
151 set script_path $argv[1]
152 set shortcut (path basename (path change-extension '' $script_path))
154 function $shortcut --inherit-variable script_path
155 set existing_venv "$VIRTUAL_ENV"
157 source ~/repos/scripts/.venv/bin/activate.fish
158 bash ~/repos/scripts/$script_path $argv
160 # If we were in a virtualenv before we started running this
161 # script, make sure we re-enable it afterwards.
162 #
163 # If not, we just need to deactivate the scripts venv.
164 if test -z "$existing_venv"
165 deactivate
166 else
167 source "$existing_venv/bin/activate.fish"
168 end
169 end
170end
172function __create_python_script_alias
173 set script_path $argv[1]
174 set shortcut (path basename (path change-extension '' $script_path))
176 function $shortcut --inherit-variable script_path
177 ~/repos/scripts/.venv/bin/python3 ~/repos/scripts/$script_path $argv
178 end
179end
181__create_bash_script_alias text/pp_xml.sh
183__create_python_script_alias fs/cdir.py
184__create_python_script_alias git/find_big_commits.py
185__create_python_script_alias git/git-cloc.py
186__create_python_script_alias images/chunky_pixels.py
187__create_python_script_alias images/copycrop.py
188__create_python_script_alias images/kn_cover_image.py
189__create_python_script_alias images/images_only_pdf.py
190__create_python_script_alias images/pdfthumb.py
191__create_python_script_alias images/reborder.py
192__create_python_script_alias images/squarify.py
193__create_python_script_alias images/srgbify.py
194__create_python_script_alias images/tint_image.py
195__create_python_script_alias text/fix_twemoji.py
196__create_python_script_alias text/fix_twitter_thread.py
197__create_python_script_alias text/natsize.py
198__create_python_script_alias text/noplaylist.py
199__create_python_script_alias text/smartify.py
200__create_python_script_alias text/sumsizes.py
201__create_python_script_alias web/download_instagram.py
202__create_python_script_alias web/yt-dlp.py