Ghostty + Zellij + Fish Shell

Ghostty just dropped, let's intergrate it with my previous Terminal stack of Zellij and Fish!

Ghostty + Zellij + Fish Shell
28 Dec 2024
|
3 min read

If you have some issues, questions or comments, there is a GitHub discussion about this procedure!

Why Ghostty?...

At first I did not understand why Ghostty got so much hype. I've used WezTerm and was pretty satisfied with it (even did some fun scripting for transparent window background when the window is out of focus).

Although there were some quirks with WezTerm:

  • I could not get WezTerm to forward macOS CMD + ... keybindings to Zellij,
    This is what we're gonna solve.

  • I had to set a separate DPI and font size for each of my external displays and the integrated Macbook screen.
    Automatically works in Ghostty.

Install...

  • Ghostty
    Well, head over to the Ghostty install docs. I assume you already did that if you clicked on this article.

  • Fish
    A shell environment - but modern. Easily extendable.

  • Zellij
    Zellij is basically a modern type of tmux, written in Rust - of course.

Integrate

We have some requirements:

  • Automatically launch Zellij when opening a Terminal in Ghostty

  • We do not want Zellij if we're in another Terminal - such as the integrated Terminal in JetBrains IDEs

  • Forward typical macOS tab-management keybindings to Zellij

Ghostty as an initial-command config option but I didn't feel like the Ghostty config was the right place for our environment check. Additionally, we would loose the automatic shell detection when overriding this config option.

For keybindings, I do not need native Terminal tabs but rather want to use tabs + panes in Zellij. So I want to use the usual key combinations of Command + n (new tab) and Command + Option + Arrow for switching between them.

Ghostty ghostty Config file

See Ghostty Configuration docs, I've placed my config in ~/.config/ghostty/ghostty.

The default configuration works really well for me out of the box, I've only made some minor adjustments:

 1mouse-scroll-multiplier = 0.5
 2
 3window-decoration = true
 4window-padding-x = 8
 5window-padding-y = 8
 6
 7theme = catppuccin-mocha
 8font-feature = -liga
 9
10macos-titlebar-style = transparent
11
12# Unbind CMD+... keys so they will be forwarded to Zellij
13keybind = cmd+t=unbind
14keybind = cmd+n=unbind
15keybind = cmd+c=unbind
16keybind = cmd+w=unbind
17keybind = cmd+opt+left=unbind
18keybind = cmd+opt+right=unbind

Fish config.fish

Ghostty should automatically detect your Shell if you've installed Fish correctly. If this is not the case, add the following config line to your Ghostty config file.

1 +shell-integration = fish

See the Fish tutorial docs for more info, typically the config should be placed in ~/.config/fish/config.fish.

 1# Unset the default fish greeting text which messes up Zellij
 2set fish_greeting
 3
 4# Check if we're in an interactive shell
 5if status is-interactive
 6
 7    # At this point, specify the Zellij config dir, so we can launch it manually if we want to
 8    export ZELLIJ_CONFIG_DIR=$HOME/.config/zellij
 9
10    # Check if our Terminal emulator is Ghostty
11    if [ "$TERM" = "xterm-ghostty" ]
12        # Launch zellij
13        eval (zellij setup --generate-auto-start fish | string collect)
14    end
15end

Zellij config.kdl Config file

Above, we've specified the ZELLIJ_CONFIG_DIR, so place your config.kdl in that folder, in my case ~/.config/zellij/config.kdl

 1keybinds {
 2    normal {
 3        bind "Super c" { Copy; }
 4        bind "Super Alt Left" { GoToPreviousTab; }
 5        bind "Super Alt Right" { GoToNextTab; }
 6        bind "Super w" { CloseTab; }
 7        bind "Super n" { NewTab; }
 8        bind "Super t" { NewTab; }
 9    }
10}

If Zellij is not starting into Fish shell, add the following config line to your config.kdl

1 +default_shell "fish"

And this is what we got!


Read more...