Functions for the Fish Shell, making common tasks more convenient.
Backup any existing ~/.config/fish, then:
git clone https://git.sr.ht/~razzi/fish-functions ~/.config/fishIn previous versions, other fish config including abbrs were included as well. That changed much more frequently than the functions, so I split them out.
Now they are at https://git.sr.ht/~razzi/.dotfiles (see that repository's README for installation instructions).
fishInteractive Utilities- File Manipulation
- Zipfile Utilities
- Text Utilities
fishScripting Utilities- Environment Utilities
- Symlink Utilities
gitUtilitieslimaUtilitiesvimUtilities- Postgres Utilities
- Date Utilities
- debian Utilities
- macOS Utilities
Fish functions designed to be typed and run in the shell.
Adds an abbr and syncs your abbrs to ~/.config/fish/conf.d/abbrs.fish.
This way the abbr will be loaded the next time you open your shell.
Without abbr-add, you can use abbr -a to make your own abbrs,
and add abbr -a calls to your fish config manually,
but I recommend using abbr-add and tracking
~/.config/fish/conf.d/abbrs.fish in version control.
All abbr options are passed to this command, so for example you can run:
$ abbr-add --position anywhere isntall installRecommended abbreviation: abbr-add ab abbr-add
Erases an abbr and removes it from ~/.config/fish/conf.d/abbrs.fish.
Recommended abbreviation: abbr-add ae abbr-erase
Completion: completes abbr names.
Copies the arguments that follow clip to the clipboard.
$ clip cat ~/.ssh/id_ed25519.pub
# now "cat ~/.ssh/id_ed25519.pub" is on the clipboard
$ echo (fish_clipboard_paste)
cat ~/.ssh/id_ed25519.pubThis is useful when you want to copy a command to your clipboard (possibly to paste the command into documentation).
You can press the up arrow or control+p to get to the previous command,
then hit control-a to move your cursor to the start, prepend clip ,
and you can quickly copy a command.
If you want to copy the output of a command, pipe it to fish_clipboard_copy:
$ echo 1 | fish_clipboard_copy
$ echo (fish_clipboard_paste)
1Edit the last-edited fish function again.
Save the last-edited fish function.
$ function hi
echo hi
end
$ funcsave-last
funcsave: wrote /Users/razzi/.config/fish/functions/hi.fishRecommended abbreviation: abbr-add fs funcsave-last
Make a directory and cd into it.
$ mkdir-cd folder
folder $Recommended abbreviation: abbr-add mc mkdir-cd
Creates a copy of file as file.bak.
$ ls
README.md
$ backup README.md
$ ls
README.md README.md.bakcp with some extra behaviors.
Automatic recursive copy for directories. Rather than only copying the files from a directory, copies the directory itself.
Also uses -i flag by default, which will warn you if a copy would overwrite a destination file.
Example:
$ mkdir testdir
$ touch testdir/file.txt
$ mkdir destdir
# Standard cp needs -r flag
$ cp testdir/ destdir/
cp: testdir/ is a directory (not copied).
# And does not preserve the source folder
$ cp -r testdir/ destdir/
$ ls destdir/
file.txt
# Cleaning up...
$ rm destdir/file.txt
# In contrast, using `copy` function:
$ copy testdir/ destdir/
$ ls destdir/
testdirRecommended abbreviation: abbr-add cp copy
If you do this abbreviation, use command cp for the low-level cp.
Creates a file, including parent directories as necessary.
$ create-file a/b/c
$ tree
.
└── a
└── b
└── cMoves a directory's contents to the current directory and removes the empty directory.
$ tree
.
└── a
└── b
└── c
$ eat a
$ tree
.
└── b
└── cIf a file in the current directory would be overwritten by eat, it will error with exit status 1.
An illustration of this:
$ tree
.
├── dir-a
│ └── dir-b
│ └── some_file
└── dir-b
└── would_be_overwritten
3 directories, 3 files
$ eat dir-a
eat: file would be overwritten: ./dir-bLike mv but uses -i flag by default,
which will warn you if mv would overwrite a destination file.
Also warns you if you are trying to move a directory symlink which is ending in slash:
$ mkdir mydir
$ ln -s mydir mylink
$ mv mylink/ renamed
mv: cannot move 'mylink/' to 'renamed': Not a directorymove gives a more descriptive error:
$ move mylink/ renamed
move: `from` argument "mylink/" is a symlink with a trailing slash.
move: to rename a symlink, remove the trailing slash from the argument.This arises because tab completion adds the slash. Completion for move could avoid the slash, but then again you might want to move a file within the symlinked directory.
Move the latest download to destination directory, which is the current directory if none is specified.
Recommended abbreviation: abbr-add mvl move-last-download
rm with an extra behavior.
If removing a directory with write-protected .git, confirm once to ensure the git directory is desired to be removed.
$ ls -a dodo
. .. .git x
$ remove dodo
Remove .git directory dodo/.git?> yUsing plain rm:
$ rm -r dodo
override r--r--r-- razzi/staff for dodo/.git/objects/58/05b676e247eb9a8046ad0c4d249cd2fb2513df? y
override r--r--r-- razzi/staff for dodo/.git/objects/f3/7f81fa1f16e78ac451e2d9ce42eab8933bd99f? y
override r--r--r-- razzi/staff for dodo/.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391? ^C
$ rm -rf dodoRecommended abbreviation: abbr-add rm remove
If you do this abbreviation, use command rm for the low-level rm.
Rename a backup such as file.bak to remove the .bak extension.
$ ls
README.md README.md.bak
$ restore README.md.bak
$ ls
README.mdUnzips a .zip archive without polluting the current directory, by creating a
directory even if the zipfile does not have a folder level.
Unzip a zip directory and cd into it. Uses clean-unzip to create a folder if
the zipfile doesn't have one.
$ unzip-cd files.zip
Archive: files.zip
extracting: out/a.txt
extracting: out/b.txt
files $ ls
a.txt b.txtSplits input on whitespace and prints the column indicated.
$ echo 1 2 | coln 2
2Prints the row of input indicated.
$ seq 3 | row 2
2Skips the first n lines of stdin.
$ seq 5 | skip-lines 2
3
4
5Take the first n lines of standard input.
$ seq 5 | take 3
1
2
3Count the words from standard input. Like wc -w but does not put spaces around the number.
$ echo a b | word-count
2
# Compare to:
$ echo a b | wc -w
2Count the lines from standard input. Like wc -l but does not put spaces around the number.
$ seq 3 | line-count
3
# Compare to:
$ seq 3 | wc -l
3Count the characters from standard input. Like wc -c but does not put spaces around the number.
$ echo -n a b | char-count
3
# Compare to:
$ echo -n a b | wc -c
3Test if the value is the empty string.
$ string-empty ''
$ echo $status
0Can be used to test for arguments:
$ function something
if string-empty $argv
echo No arguments passed
else
echo Arguments were passed
end
end
$ something
No arguments passed
$ something 1
Arguments were passedIf you use this on a variable, be sure to get the variable's value using $:
$ if string-empty $VIRTUAL_ENV
echo in venv
endsince string-empty VIRTUAL_ENV will always return false.
Test if $file exists.
Check if $path is a directory.
Check if $path is a symlink.
Prompts the user for confirmation. Exit with status according to whether they answered y, Y, yes, or YES.
Just the current directory name, please.
mydir $ curdir
mydirYou probably won't need this interactively since the current directory is usually part of your fish_prompt,
but this is useful for scripting.
Like echo, but without the $ or capitalization.
$ echo-variable user
razzi
$ echo $USER
razziRecommended abbreviation: abbr-add ev echo-variable
Completion: completes environment variable names.
Prompt for a password. Does not echo entered characters.
$ readpass email
â—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Źâ—Ź
$ echo $email
[email protected]Create a symbolic link, using absolute paths.
~/dotfiles $ symlink .prettierrc ~
~/dotfiles $ cat ~/.prettierrc
singleQuote: true
semi: falseWithout using absolute paths:
~/dotfiles $ ln -s .prettierrc ~
~/dotfiles $ cat ~/.prettierrc
cat: /Users/razzi/.prettierrc: Too many levels of symbolic linksRemove a symlink. Errors if the file is not a symlink.
Recommended abbreviation: abbr-add us unsymlink
List symlinks in the given directory, or the current directory if none is passed.
Create a symlink from $file to the home directory (~).
Sample usage:
.dotfiles $ link-rc .tmux.conf
.dotfiles $ head -1 ~/.tmux.conf
set -g prefix ^SpaceRecommended abbreviation: abbr-add lrc link-rc
Clone a git repository into the current directory (or the optional $destination), and cd into it.
If a folder by that name already exists, great, you probably already cloned it, just cd into the directory and pull.
If it's trying to clone into a non-empty directory, make a new folder in that directory with the repository name and clone into that, instead of erroring.
Recommended abbreviation: abbr-add cc clone-cd
Like clone-cd but clones with --depth=1 for speed.
Adds untracked changes and commits them with a WIP message. Additional arguments are added to the WIP message.
I use this instead of git stash so that changes are associated with the branch they're on, and the commit is tracked in the reflog.
$ git stat
## master
M tests.py
$ git switch -c testing
$ wip failing tests
[testing 0078f7f] WIP failing tests
$ git switch -A wrapper for git add that defaults to git add . if no arguments given, rather than erroring.
Recommended abbreviation: abbr-add ga git-add
Like git commit -m without the need to quote the commit message.
If no commit message is given and there's only 1 file changed, commit "(Add / Update / Delete) (that file)".
$ git-commit
[master c77868d] Update README.md
1 file changed, 57 insertions(+), 18 deletions(-)
$ git reset @^
Unstaged changes after reset:
M README.md
$ git-add
$ git-commit Fix typo in README.md
[master 0078f7f] Fix typo in README.md
1 file changed, 57 insertions(+), 18 deletions(-)Recommended abbreviation: abbr-add gc git-commit
Change the protocol of the current git repository to be git rather than https.
Useful if you clone an https url but you want to push or pull later.
Example usage:
ronin $ git push
fatal: unable to access 'https://git.sr.ht/~razzi/ronin/': The requested URL returned error: 403
ronin $ git-protocol-https-to-git
ronin $ git push
Everything up-to-date
Recommended abbreviation: abbr-add gpro git-protocol-https-to-git
Add a pattern to the .gitignore.
Recommended abbreviation: abbr-add giti gitignore
Opens the url of your current git repository in the browser.
By default it will open the upstream remote, however you can pass the specific remote you'd like to open.
Some history here: before the gh cli was released,
there was hub, a command to interact with github from
the command line. It had a weird design; it wrapped git commands, and wanted you to alias git=hub
(I never did). However one thing it did better than the gh command is that hub browse would open
the (github) git repository in the browser. I stopped installing hub but I still wanted
this functionality, so I recreated it as a single-purpose command and added the ability
to open different remotes.
Completion: completes remote names.
Connect to a lima virtual machine. Defaults the machine named default.
Creates and starts the machine as necessary, so it works in 1 command.
Connect to a Lima virtual machine over VNC.
Creates and starts the machine as necessary, like lima-ssh.
Install a vim plugin using the builtin vim plugin mechanism.
Ensure that a fresh database by the name given is created. Drops a database by that name if it exists, clearing database connections as necessary.
Renames a database.
Prints the date in ISO format.
$ isodate
2020-01-28Prints the date and time in ISO format.
$ isodatetime
2025-03-07T23:11:53Show the apt description for a given package.
Prints the current wifi network name.
Prints the current wifi network password. It will pop up with an authentication modal; enter your login username and password and hit enter and it will print the wifi password to the command line.
Turns the wifi off and on again.