Personal Fish Functions

Previously I wrote about my switch from GNU Bash to Fish. As a result I have given up writing shell scripts in favor of using Perl, Python, and similar languages. But there are a series of short functions from Bash that I decided to port over to Fish, as I did not feel they were large enough to warrant a script in one of those other languages. So today I want to share some custom Fish functions that I find useful.

Very Quick Overview of Fish Functions

Fish provides the appropriately named function for defining new functions. You define each function in its own file in the functions sub-directory of your Fish configuration, e.g. ~/.config/fish/functions/ on Linux systems. Each file ends with .fish so, for example, to create the wc-lr function you would create ~/.config/fish/functions/

Count Lines of Code

I’ll begin with the wc-lr command mentioned above:

function wc-lr --description "Recursively apply 'wc -l' on the current directory"
    find . -type f -print0 | xargs --null -I '{}' wc -l '{}' | awk '{total += $1} END {print total}'

Note: The definition includes the --description parameter which is useful for providing accessible documentation.

The wc-lr command counts and totals the lines of all files in the current directory and its sub-directories. Source lines of code (SLOC) are poor metric for complexity, but nonetheless remains a popular statistic in the software industry. So this function calculates SLOC. I use it on occasion to satisfy my curiosity about the amount of code in my projects. For example, the game my friends and I are developing: 15,030 lines of Lua at this time of writing.

Building Software

Compiling software on Linux often begins with running two programs:

  1. Configure
  2. Make

I do this so often that I have a function for this purpose.

function configure-and-make --description "Compile by running ./configure and make"
    switch (count $argv)
        case "0"
            sh ./configure --prefix=/usr/local; and time make
        case "*"
            sh ./configure --prefix=$argv[1]; and time make

It uses Fish’s count function to support an optional argument: the path where I want to install the program. By default it uses /usr/local but sometimes I want to install them elsewhere, such as:

# Prepare to install in /usr/local
$ configure-and-make

# Install in /opt/php instead
$ configure-and-make /opt/php

A Better ls Command

function lss --description "Show more detailed 'ls' output"
    ls -l --all --human-readable --classify --color=always $argv | less -XRF

Just try it sometime. Note that the pipe is not necessary. Pressing Alt+p will tack | less -XRF on to the end of any command.

Copy a Website Locally

This function uses GNU Wget to create a local copy of a website for me to read later:

function web-cp --description "Create a local copy of a website"
    wget --no-parent --wait=20 --recursive --convert-links $argv

I like to keep a local copy of certain programming websites so that I can refer to the documentation even if I have no Internet connection.


A short article, I know. The Fish documentation explains the useful built-ins available for writing functions. In a future article I will share some of the large Bash functions that I converted to scripts in other languages. Until then please share any useful functions of your own if you’re a fellow Fish user.


Add Your Thoughts

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s