DEV Community

Maksym
Maksym

Posted on • Edited on

Complete Guide: Fish Shell Adding Custom Functions

Fish in wizard hat

WARNING
Some of the commands used in this tutorial may not work on your machine, especially if you're using macOS instead of Linux. Tools like free, top, or certain awk filters behave differently across systems. If you run into issues, try using macOS alternatives.

Fish (Friendly Interactive Shell) is a modern, user-friendly command-line shell that offers powerful features like syntax highlighting, autosuggestions, and easy customization. This guide will walk you through downloading Fish and creating custom functions to enhance your command-line experience.

Getting Started with Fish

Launch Fish by typing fish in your terminal, or start a new terminal session if you've set it as your default shell.

Basic Fish Configuration

Fish stores its configuration in ~/.config/fish/. The main configuration file is config.fish.

# Create configuration directory if it doesn't exist
mkdir -p ~/.config/fish

# Edit main configuration file
nano ~/.config/fish/config.fish
Enter fullscreen mode Exit fullscreen mode

Understanding Fish Functions

Fish functions are similar to aliases or shell functions in other shells, but more powerful. They can:

  • Accept arguments
  • Include complex logic
  • Be saved persistently
  • Have descriptions and help text

Function Storage Locations

  • User functions: ~/.config/fish/functions/
  • System-wide functions: /usr/share/fish/functions/
  • Session functions: Defined in memory for current session only

Creating Your First Fish Function

Method 1: Interactive Function Creation

# Start Fish and use the function editor
function hello
    echo "Hello, $argv!"
end

# Save the function permanently
funcsave hello
Enter fullscreen mode Exit fullscreen mode

Method 2: Creating Function Files

Create a file in ~/.config/fish/functions/ with the function name:

# Create the functions directory
mkdir -p ~/.config/fish/functions

# Create a function file
nano ~/.config/fish/functions/hello.fish
Enter fullscreen mode Exit fullscreen mode

Add the function content:

function hello --description "Say hello to someone"
    if test (count $argv) -eq 0
        echo "Hello, World!"
    else
        echo "Hello, $argv!"
    end
end
Enter fullscreen mode Exit fullscreen mode

Practical Fish Function Examples

1. Enhanced Directory Navigation

# ~/.config/fish/functions/mkcd.fish
function mkcd --description "Create directory and cd into it"
    mkdir -p $argv[1] && cd $argv[1]
end
Enter fullscreen mode Exit fullscreen mode

2. Git Shortcuts

# ~/.config/fish/functions/gst.fish
function gst --description "Git status with short format"
    git status --short --branch
end

# ~/.config/fish/functions/glog.fish
function glog --description "Pretty git log"
    git log --oneline --decorate --graph --all
end

# ~/.config/fish/functions/gcm.fish
function gcm --description "Git commit with message"
    if test (count $argv) -eq 0
        echo "Usage: gcm 'commit message'"
        return 1
    end
    git commit -m "$argv"
end
Enter fullscreen mode Exit fullscreen mode

3. System Information Functions

# ~/.config/fish/functions/sysinfo.fish
function sysinfo --description "Display system information"
    echo "System Information:"
    echo "=================="
    echo "Hostname: "(hostname)
    echo "User: "$USER
    echo "OS: "(uname -s)
    echo "Kernel: "(uname -r)
    echo "Uptime: "(uptime | cut -d',' -f1 | cut -d' ' -f4-)
    echo "Memory: "(free -h | grep '^Mem:' | awk '{print $3"/"$2}')
    echo "Disk Usage: "(df -h / | tail -1 | awk '{print $5" used"}')
end
Enter fullscreen mode Exit fullscreen mode

4. Development Environment Functions

# ~/.config/fish/functions/serve.fish
function serve --description "Start a simple HTTP server"
    set port 8000
    if test (count $argv) -gt 0
        set port $argv[1]
    end

    if command -v python3 >/dev/null
        python3 -m http.server $port
    else if command -v python >/dev/null
        python -m SimpleHTTPServer $port
    else
        echo "Python not found"
        return 1
    end
end

# ~/.config/fish/functions/venv.fish
function venv --description "Python virtual environment helper"
    switch $argv[1]
        case create
            python3 -m venv $argv[2]
        case activate
            source $argv[2]/bin/activate.fish
        case deactivate
            deactivate
        case '*'
            echo "Usage: venv [create|activate|deactivate] [name]"
    end
end
Enter fullscreen mode Exit fullscreen mode

5. File and Text Manipulation

# ~/.config/fish/functions/extract.fish
function extract --description "Extract various archive formats"
    if test (count $argv) -eq 0
        echo "Usage: extract <archive_file>"
        return 1
    end

    switch $argv[1]
        case '*.tar.bz2'
            tar xjf $argv[1]
        case '*.tar.gz'
            tar xzf $argv[1]
        case '*.bz2'
            bunzip2 $argv[1]
        case '*.rar'
            unrar x $argv[1]
        case '*.gz'
            gunzip $argv[1]
        case '*.tar'
            tar xf $argv[1]
        case '*.tbz2'
            tar xjf $argv[1]
        case '*.tgz'
            tar xzf $argv[1]
        case '*.zip'
            unzip $argv[1]
        case '*.Z'
            uncompress $argv[1]
        case '*.7z'
            7z x $argv[1]
        case '*'
            echo "Don't know how to extract '$argv[1]'"
            return 1
    end
end
Enter fullscreen mode Exit fullscreen mode

Advanced Function Features

Function Arguments and Options

function myfunction --description "Example function with options"
    argparse 'h/help' 'v/verbose' 'o/output=' -- $argv
    or return

    if set -q _flag_help
        echo "Usage: myfunction [options] <input>"
        echo "Options:"
        echo "  -h, --help     Show this help"
        echo "  -v, --verbose  Verbose output"
        echo "  -o, --output   Specify output file"
        return
    end

    if set -q _flag_verbose
        echo "Verbose mode enabled"
    end

    if set -q _flag_output
        echo "Output file: $_flag_output"
    end

    echo "Processing: $argv"
end
Enter fullscreen mode Exit fullscreen mode

Using Variables and Conditionals

function backup --description "Backup files with timestamp"
    set timestamp (date +%Y%m%d_%H%M%S)

    if test (count $argv) -eq 0
        echo "Usage: backup <file1> [file2] ..."
        return 1
    end

    for file in $argv
        if test -f $file
            cp $file "$file.backup_$timestamp"
            echo "Backed up: $file -> $file.backup_$timestamp"
        else
            echo "File not found: $file"
        end
    end
end
Enter fullscreen mode Exit fullscreen mode

Managing Fish Functions

Listing Functions

# List all functions
functions

# List functions matching a pattern
functions | grep git

# Show function definition
functions functionname
Enter fullscreen mode Exit fullscreen mode

Editing Functions

# Edit a function interactively
funced functionname

# Save changes permanently
funcsave functionname
Enter fullscreen mode Exit fullscreen mode

Removing Functions

# Remove from current session
functions -e functionname

# Remove permanently
rm ~/.config/fish/functions/functionname.fish
Enter fullscreen mode Exit fullscreen mode

Fish Configuration Tips

Setting Environment Variables

# In ~/.config/fish/config.fish
set -gx EDITOR vim
set -gx PATH $HOME/bin $PATH
set -gx GOPATH $HOME/go
Enter fullscreen mode Exit fullscreen mode

Creating Aliases

# In ~/.config/fish/config.fish
alias python    'python3'
alias l         'ls -a'
alias ll        'ls -la'
alias grep      'grep --color=auto'
alias ..        'cd ..'
alias ...       'cd ../..'
alisa c         'clear' 
Enter fullscreen mode Exit fullscreen mode

Custom Prompt

# ~/.config/fish/functions/fish_prompt.fish
function fish_prompt
    set_color $fish_color_cwd
    echo -n (basename (prompt_pwd))
    set_color normal
    echo -n ' $ '
end
Enter fullscreen mode Exit fullscreen mode

Troubleshooting Common Issues

Function Not Loading

  1. Check function file location
  2. Verify syntax with fish -n ~/.config/fish/functions/functionname.fish
  3. Reload Fish configuration: source ~/.config/fish/config.fish

Best Practices

  1. Use descriptive function names - Make them easy to remember
  2. Add descriptions - Use the --description flag
  3. Handle arguments properly - Check for required arguments
  4. Provide help information - Include usage examples
  5. Test functions thoroughly - Especially error conditions
  6. Keep functions focused - One function, one purpose
  7. Use meaningful variable names - Improve readability
  8. Comment complex logic - Help future you understand the code

Conclusion

Fish shell offers a powerful and user-friendly environment for command-line work. With custom functions, you can automate repetitive tasks, create shortcuts for complex commands, and build a personalized toolkit that matches your workflow.

Start with simple functions and gradually build more complex ones as you become comfortable with Fish's syntax and capabilities. The investment in learning Fish and creating custom functions will pay dividends in improved productivity and a more enjoyable command-line experience.

Remember to back up your Fish configuration regularly, and consider using version control to track changes to your functions and configuration files.

Top comments (0)