How to Use SDKMAN! with Fish Shell: A Detailed Guide

PawanPawan
3 min read

TL;DR: While SDKMAN! is primarily designed for Bash/Zsh shells, you can make it work with Fish shell using a simple wrapper function that bridges the gap between Fish and Bash.

The Problem with SDKMAN! and Fish Shell

If you're a Fish shell user trying to use SDKMAN! (Software Development Kit Manager), you've probably encountered errors like:

~/.sdkman/etc/config (line 1): Unsupported use of '='. In fish, please use 'set sdkman_auto_answer false'.

This happens because SDKMAN!'s scripts are written in Bash/Zsh syntax, which isn't compatible with Fish shell's unique syntax.

The Quick Solution: A Fish Shell Wrapper

Instead of converting all of SDKMAN!'s scripts to Fish (which would be time-consuming and break with updates), we can create a simple wrapper function that lets Fish and SDKMAN! work together seamlessly.

Step 1: Install SDKMAN!

First, make sure you have SDKMAN! installed:

curl -s "https://get.sdkman.io" | bash

Step 2: Create the Wrapper Function Initialization Script

First, create a new file in your Fish config directory if it doesn't already exist:

mkdir -p ~/.config/fish/conf.d

Then, create a new file called sdkman-init.fish in the conf.d directory:

touch ~/.config/fish/conf.d/sdkman-init.fish

Finally, write the script in your favorite text editor, by following these steps:

  1. Open your terminal and type the command to open the file in your preferred text editor. For example, using nvim:

     nvim ~/.config/fish/conf.d/sdkman-init.fish
    
  2. Copy and paste the following script into the file:

     function sdk --description 'SDKMAN! wrapper for Fish shell'
         set -q SDKMAN_DIR; or set -gx SDKMAN_DIR "$HOME/.sdkman"
         set -q SDKMAN_CANDIDATES_API; or set -gx SDKMAN_CANDIDATES_API "https://api.sdkman.io/2"
    
         if test -f "$SDKMAN_DIR/var/platform"
             set -gx SDKMAN_PLATFORM (cat "$SDKMAN_DIR/var/platform")
         end
         command bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && sdk $argv"
    
         if contains -- "$argv[1]" "install" "uninstall" "use" "default" "env"
             set -l candidates (cat "$SDKMAN_DIR/var/candidates")
             for candidate in (string split ',' $candidates)
                 set -l candidate_dir "$SDKMAN_DIR/candidates/$candidate/current"
                 if test -L "$candidate_dir"; or test -d "$candidate_dir"
                     if not contains "$candidate_dir/bin" $PATH
                         set -gx PATH "$candidate_dir/bin" $PATH
                     end
                 end
             end
         end
     end
    
     complete -c sdk -f
     complete -c sdk -a "install uninstall list use current upgrade version default home env clear help offline selfupdate update flush" -d "SDKMAN! command"
     complete -c sdk -n "__fish_seen_subcommand_from install uninstall list use current upgrade version default home" -a "(cat $HOME/.sdkman/var/candidates | string split ',')" -d "SDK candidate"
    
  3. Save the file and exit the text editor.

Step 3: Initialize fish shell with sdkman

source ~/.config/fish/conf.d/sdkman.fish

Get the complete file as a gist on my github.

How It Works

The wrapper function:

  1. Sets up necessary SDKMAN! environment variables.

  2. Uses Bash to execute SDKMAN! commands.

  3. Updates Fish's PATH after installing or switching versions.

  4. Provides command completion for common SDKMAN! operations.

Using SDKMAN! in Fish

Now you can use SDKMAN! commands just like in Bash:

# List available Java versions
sdk list java

# Install a specific Java version (Eclipse Temurin in this case)
sdk install java 17.0.2-tem

# Use a specific Java version
sdk use java 17.0.2-tem

Conclusion

This wrapper provides a practical solution for Fish shell users who want to use SDKMAN! without converting all its scripts or switching shells. It maintains compatibility with SDKMAN! updates while providing most of the functionality you need for day-to-day development.

FAQ

Q: Will this break when SDKMAN! updates? A: No, since we're using Bash to execute SDKMAN! commands, it should continue working with updates.

Q: Does this work on all operating systems? A: Yes, as long as you have both Fish and Bash installed.

Q: Can I contribute to making SDKMAN! work natively in Fish? A: Yes! The SDKMAN! project is open source and welcomes contributions.

0
Subscribe to my newsletter

Read articles from Pawan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pawan
Pawan