Skip to content

feat(wrapperModules.ghostty): init#393

Open
nouritsu wants to merge 2 commits intoBirdeeHub:mainfrom
nouritsu:ghostty
Open

feat(wrapperModules.ghostty): init#393
nouritsu wants to merge 2 commits intoBirdeeHub:mainfrom
nouritsu:ghostty

Conversation

@nouritsu
Copy link
Copy Markdown
Contributor

Add wrapperModule: ghostty
https://ghostty.org/

@nouritsu
Copy link
Copy Markdown
Contributor Author

See #394

@nouritsu nouritsu force-pushed the ghostty branch 2 times, most recently from d8a19f8 to 0ae5fb9 Compare March 29, 2026 22:19
@nouritsu
Copy link
Copy Markdown
Contributor Author

There is another design decision -

Everytime I run ghostty using the wrapper, it creates an empty file in ~/.config/wezterm/config/ghostty/config.ghostty.

So on a second run the program logs

warning: error reading optional config file, not loading err=error.FileIsEmpty path=/home/aneesh/.config/ghostty/config.ghostty

Should I make it generate an empty config file in a store path that ghostty thinks is in the $XDG_CONFIG_HOME path?

@nouritsu
Copy link
Copy Markdown
Contributor Author

nouritsu commented Mar 29, 2026

I can see that Helix does something similar by reassigning XDG_CONFIG_HOME to a placeholder config directory. Something similar to that should work?

Tried doing this, it works alright but now my configs for fish, starship etc. are not picked up. If this is intended behaviour, I will clean things up and open the PR.

The issue is that ghostty checks for/creates the config.ghostty BEFORE parsing the config keys passed through the CLI.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 29, 2026

Im not sure for now I will need to try it and look at the docs, I'll let you know

That looks to me like it is still trying to load the regular config even with your 2 flags set?

If so, that may technically be fine, unless the presence of that file causes ours not to load? But it would be nice to provide an option to choose if that happens or not?

Does ours load before or after? (edit: ok, so after, so, ours would win?) Are there other files we may want to provide, or is that the only file? If its only the 1 file I would prefer to not change the whole XDG config path if we can avoid it?

We will need to look into it further.

Tried doing this, it works alright but now my configs for fish, starship etc. are not picked up. If this is intended behaviour, I will clean things up and open the PR.

Would you mind sharing a test config I could use when I go to look at it (if one is even needed to see the behavior anyway)

How are you configuring your shell? That would be what has the config for those things

@nouritsu
Copy link
Copy Markdown
Contributor Author

nouritsu commented Mar 29, 2026

Using the current approach, it seems to load the config file

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    wrappers.url = "path:/path/to/flake";
  };

  outputs = {
    nixpkgs,
    wrappers,
    ...
  }: let
    system = "x86_64-linux";
    pkgs = nixpkgs.legacyPackages.${system};
  in {
    packages.${system}.default = wrappers.wrappers.ghostty.wrap [
      {
        inherit pkgs;
        package = pkgs.ghostty;
      }
      {
        settings = {
          font-size = 26;
        };
      }
    ];
  };
}

This spawns a terminal in with my fish, starship etc. config loaded and the font size set to 26. The logs say

warning: error reading optional config file, not loading err=error.FileIsEmpty path=/home/aneesh/.config/ghostty/config.ghostty

# ...

info: reading configuration file path=/nix/store/ayc0g7cg0fmfq6jfyqhzvl87gg1s05x6-ghostty-1.3.1/ghostty.conf

So it does work as intended, however the file config.ghostty is still created in ~/.config/ghostty. It is just an empty file which causes ghostty to print this warning, perhaps we could create a file with a comment line (if it does not already exist)?

There is a test case - seeing what happens when the .config configuration file has config options set and we also pass in --config-file from the command line. However I will only be able to test that in about 15 hours

@nouritsu
Copy link
Copy Markdown
Contributor Author

nouritsu commented Mar 29, 2026

I configure my shell using the NixOS fish module and starship using the starship home module.

Both should generate configs in my home .config so it makes sense that ghostty can read from it.

(not using wrappers, yet)

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 29, 2026

yeah it should be picking up on those configs as long as it runs fish, cause starship is all done inside the shell.

On first startup, without the file existing

info(config): creating template config file: path=/home/birdee/.config/ghostty/config
info(config): config-default-files unset, discarding configuration from default files
info(config): loading config-file path=/nix/store/gg8avccs4823bs0lsny260xasi78v7s3-ghostty-1.2.3/ghostty.conf

on subsequent startups

info: reading configuration file path=/home/birdee/.config/ghostty/config
info(config): config-default-files unset, discarding configuration from default files
info(config): loading config-file path=/nix/store/gg8avccs4823bs0lsny260xasi78v7s3-ghostty-1.2.3/ghostty.conf

^ So, yes, it makes the config, and then proceeds not to use it at all because you have --config-default-files=false set

That is somewhat odd behavior, but I don't see the harm in it generating the file if it is not already present, as long as it is not using it, or using it in addition

I would assume it is just saying "read" when it means "check if its there so we can make the template config or not and possibly check that they are valid settings"

The template config it generates is

# This is the configuration file for Ghostty.
#
# This template file has been automatically created at the following
# path since Ghostty couldn't find any existing config files on your system:
#
#   /home/birdee/.config/ghostty/config
#
# The template does not set any default options, since Ghostty ships
# with sensible defaults for all options. Users should only need to set
# options that they want to change from the default.
#
# Run `ghostty +show-config --default --docs` to view a list of
# all available config options and their default values.
#
# Additionally, each config option is also explained in detail
# on Ghostty's website, at https://ghostty.org/docs/config.
#
# Ghostty can reload the configuration while running by using the menu
# options or the bound key (default: Command + Shift + comma on macOS and
# Control + Shift + comma on other platforms). Not all config options can be
# reloaded while running; some only apply to new windows and others may require
# a full restart to take effect.

# Config syntax crash course
# ==========================
# # The config file consists of simple key-value pairs,
# # separated by equals signs.
# font-family = Iosevka
# window-padding-x = 2
#
# # Spacing around the equals sign does not matter.
# # All of these are identical:
# key=value
# key= value
# key =value
# key = value
#
# # Any line beginning with a # is a comment. It's not possible to put
# # a comment after a config option, since it would be interpreted as a
# # part of the value. For example, this will have a value of "#123abc":
# background = #123abc
#
# # Empty values are used to reset config keys to default.
# key =
#
# # Some config options have unique syntaxes for their value,
# # which is explained in the docs for that config option.
# # Just for example:
# resize-overlay-duration = 4s 200ms

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 29, 2026

I am also not getting that error you mentioned either the first time or subsequent times

logs from first time

info: ghostty version=1.2.3
info: ghostty build optimize=ReleaseFast
info: runtime=apprt.Runtime.gtk
info: font_backend=font.main.Backend.fontconfig_freetype
info: dependency harfbuzz=12.3.0
info: dependency fontconfig=21701
info: renderer=renderer.generic.Renderer(renderer.OpenGL)
info: libxev default backend=io_uring
info(os_locale): setlocale from env result=en_US.UTF-8
info(gtk): GTK version build=4.20.3 runtime=4.20.3
info(gtk): libadwaita version build=1.8.3 runtime=1.8.3
info(config): creating template config file: path=/home/birdee/.config/ghostty/config
info(config): config-default-files unset, discarding configuration from default files
info(config): loading config-file path=/nix/store/gg8avccs4823bs0lsny260xasi78v7s3-ghostty-1.2.3/ghostty.conf
info(config): default shell source=env value=/run/current-system/sw/bin/zsh
warning(gtk_ghostty_application): setting GDK_DEBUG=
warning(gtk_ghostty_application): setting GDK_DISABLE=gles-api,vulkan
info(gtk_ghostty_application): cgroup isolation disabled via config=config.Config.LinuxCgroup.single-instance
info(opengl): loaded OpenGL 4.6
info(io_exec): found Ghostty resources dir: /nix/store/6vdfy107nlcc2il2r6ip5mjszhnmwp80-ghostty-1.2.3/share/ghostty
info(io_exec): shell integration automatically injected shell=termio.shell_integration.Shell.zsh
warning(gtk_ghostty_application): unimplemented action=apprt.action.Action.Key.cell_size
info(io_exec): started subcommand path=/bin/sh pid=683558
info(io_exec): subcommand cgroup=-

logs from second time

info: ghostty version=1.2.3
info: ghostty build optimize=ReleaseFast
info: runtime=apprt.Runtime.gtk
info: font_backend=font.main.Backend.fontconfig_freetype
info: dependency harfbuzz=12.3.0
info: dependency fontconfig=21701
info: renderer=renderer.generic.Renderer(renderer.OpenGL)
info: libxev default backend=io_uring
info(os_locale): setlocale from env result=en_US.UTF-8
info(gtk): GTK version build=4.20.3 runtime=4.20.3
info(gtk): libadwaita version build=1.8.3 runtime=1.8.3
info: reading configuration file path=/home/birdee/.config/ghostty/config
info(config): config-default-files unset, discarding configuration from default files
info(config): loading config-file path=/nix/store/gg8avccs4823bs0lsny260xasi78v7s3-ghostty-1.2.3/ghostty.conf
info(config): default shell source=env value=/run/current-system/sw/bin/zsh
warning(gtk_ghostty_application): setting GDK_DEBUG=
warning(gtk_ghostty_application): setting GDK_DISABLE=gles-api,vulkan
info(gtk_ghostty_application): cgroup isolation disabled via config=config.Config.LinuxCgroup.single-instance
info(opengl): loaded OpenGL 4.6
info(io_exec): found Ghostty resources dir: /nix/store/6vdfy107nlcc2il2r6ip5mjszhnmwp80-ghostty-1.2.3/share/ghostty
info(io_exec): shell integration automatically injected shell=termio.shell_integration.Shell.zsh
warning(gtk_ghostty_application): unimplemented action=apprt.action.Action.Key.cell_size
info(io_exec): started subcommand path=/bin/sh pid=687940
info(io_exec): subcommand cgroup=-

Edit: The error only happens if the config there is LITERALLY empty.

info: ghostty version=1.2.3
info: ghostty build optimize=ReleaseFast
info: runtime=apprt.Runtime.gtk
info: font_backend=font.main.Backend.fontconfig_freetype
info: dependency harfbuzz=12.3.0
info: dependency fontconfig=21701
info: renderer=renderer.generic.Renderer(renderer.OpenGL)
info: libxev default backend=io_uring
info(os_locale): setlocale from env result=en_US.UTF-8
info(gtk): GTK version build=4.20.3 runtime=4.20.3
info(gtk): libadwaita version build=1.8.3 runtime=1.8.3
warning: error reading optional config file, not loading err=error.FileIsEmpty path=/home/birdee/.config/ghostty/config
info(config): config-default-files unset, discarding configuration from default files
info(config): loading config-file path=/nix/store/d4z6azdf38730kkgzfdrls189l9smf91-ghostty-1.2.3/ghostty.conf
info(config): default shell source=env value=/run/current-system/sw/bin/zsh
warning(gtk_ghostty_application): setting GDK_DEBUG=
warning(gtk_ghostty_application): setting GDK_DISABLE=gles-api,vulkan
info(gtk_ghostty_application): cgroup isolation disabled via config=config.Config.LinuxCgroup.single-instance
info(opengl): loaded OpenGL 4.6
info(io_exec): found Ghostty resources dir: /nix/store/6vdfy107nlcc2il2r6ip5mjszhnmwp80-ghostty-1.2.3/share/ghostty
info(io_exec): shell integration automatically injected shell=termio.shell_integration.Shell.zsh
warning(gtk_ghostty_application): unimplemented action=apprt.action.Action.Key.cell_size
info(io_exec): started subcommand path=/bin/sh pid=782042
info(io_exec): subcommand cgroup=-

If it is missing, they create it, we don't need to.

The error also doesn't stop it from loading or anything, and it still is just going to ignore it anyway.

Its fine how you have it I think.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 29, 2026

It also appears to pick up on my starship and zsh configs, which I am using wrappers for. But that is expected, its just running the zsh from my main system environment, which is that one.

I am running it with an empty config.

I will try with a setting or 2.

Edit: still seems to work. font size 26 is absolutely gigantic

I built it in the repl :bl outputs.wrappers.ghostty.wrap { inherit pkgs; settings.font-size = 26; }

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

They have some kind of service thing? Lets patch it with the path to the final wrapper instead of the base ghostty program.

    config.filesToPatch = [
      "share/applications/*.desktop"
      "share/dbus-1/services/com.mitchellh.ghostty.service"
      "share/systemd/user/app-com.mitchellh.ghostty.service"
    ];

Otherwise, yeah this looks good to me. It only gives the warning when the file is both present and literally empty. And it doesn't use anything from it anyway.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

Oh, also, the tests are just failing because you have not ran nix fmt in the directory since adding your module so it is complaining about some formatting being not the way it wants it.

Im not always super happy with its formatting, but having a standard one is good, at least they are all equally as unreadable at first until you get used to it and then its easier to read code from random people who might format differently.

@nouritsu
Copy link
Copy Markdown
Contributor Author

If it is missing, they create it, we don't need to.

That is interesting, on my system it seems to generate an empty file at the path mentioned rather than filling it with the lines that have comments.

I will add the filesToPatch, reformat my files and messages and open the PR. It should be ready to merge after those changes.

Thank you for doing the legwork, my future PRs will be smoother! 😅

@nouritsu nouritsu force-pushed the ghostty branch 2 times, most recently from b2b1dc6 to cdb0875 Compare March 30, 2026 11:57
@nouritsu nouritsu marked this pull request as ready for review March 30, 2026 11:58
@nouritsu nouritsu changed the title (DRAFT) feat(wrapperModules.ghostty): init feat(wrapperModules.ghostty): init Mar 30, 2026
@nouritsu
Copy link
Copy Markdown
Contributor Author

nouritsu commented Mar 30, 2026

Alright, CI passes and the module builds.

There may be a few more things to sort out before this is ready to merge.

First, the maintainers documentation asks me to set the file name to wrapperModules/g/ghostty/wrapper.nix but if I do this, my configuration flake tries to search for a module.nix and fails. I see that other modules which define config.package also use module.nix instead of wrapper.nix. Does the documentation need to be updated?

And second, I wanted to add a check.nix but it appears that ghostty does not allow me to pass in --help or +help to the wrapped binary (or any other option for that matter). Other wrapped programs do not function like this AFAIK.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

the maintainers documentation asks me to set the file name to wrapperModules/g/ghostty/wrapper.nix

Lmao so it does. This is incorrect.

module.nix is correct.

it appears that ghostty does not allow me to pass in --help or +help to the wrapped binary (or any other option for that matter)

??????? That also appears to be the case. Quite mysterious.

@nouritsu
Copy link
Copy Markdown
Contributor Author

@BirdeeHub It seems that this is an issue with ghostty itself (running ghostty --font-size=26 --help or similar is invalid). Perhaps we go with a different approach of making the configuration available? Possibly the fake XDG config trick?

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

+validate-config

You would pass this in the tests

Does it work if you do config.flags."+validate-config" = true; in the check.nix file?

Edit: no

This is definitely a bug on their end. We should open an issue on their repo about this, that you cannot set --config-file and --config-default-files=false together with --help or +validate-config and possibly others.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

What we should do is file an issue on the ghostty repo telling them their terminal emulator doesnt allow you to do --help if you have provided other arguments.

Is there anything else wrapping it prevents? or is it JUST --help ?

Edit: it seems to be more than just --help, I can't override font-size either?

Edit 2: actually, it seems to be able to set settings, just not --help, and settings provided by the config file win over those provided from the command line

@nouritsu
Copy link
Copy Markdown
Contributor Author

Edit 2: actually, it seems to be able to set settings, just not --help, and settings provided by the config file win over those provided from the command line

I was just testing this and that seems to be the case. One would expect the command line to win, but it does not.

I'll ask if this behaviour can be changed in the discord.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

Honestly, I would rather not override it still

I would rather they fixed their bug.

That is definitely a bug on their end.

Would you mind filing an issue there, and linking here with it so that they can see the context and we can go here to see updates about it?

If you set any settings like --font-size=26 you can no longer validate your config or run --help and the same applies for --config-default-files=false and --config-file, which it says in the docs can be used alongside +validate-config

@BirdeeHub
Copy link
Copy Markdown
Owner

Before filing an issue, we should make sure they haven't already fixed this and nixpkgs is just behind

@nouritsu
Copy link
Copy Markdown
Contributor Author

Would you mind filing an issue there, and linking here with it so that they can see the context and we can go here to see updates about it?

I will need to get vouched first, but yeah this seems like a bug on their end. I'll see if this is being worked on and file an issue if not.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

Also, I should add, the reason I don't want to set XDG is because unless your shell config changed it, that would set XDG for your whole terminal.

So I would really rather not if we can help it for terminals, because when running stuff with the shell it could have an unintended effect

Do they have a variable we can set instead of --config-file? I suppose we would still need the other flag regardless, which would still trigger the issue...

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 30, 2026

ghostty-org/ghostty#12004

Apparently he uses discussions as issues?

Edit: Oh, I missed yours ghostty-org/ghostty#11987 Closed mine as duplicate and dropped a link to it in yours

@nouritsu
Copy link
Copy Markdown
Contributor Author

All good. I think you should reopen your discussion as mine is a vouch request which would (hopefully) allow me to contribute. Yours has more details anyway.

I also tried texting in the dev channel on discord but it didn't gain any responses there.

This merge would be pretty sick though, I've been meaning to switch from wezterm for a while now

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Mar 31, 2026

Im thinking it might just be OK for now, because this is almost certainly a bug they will fix?

But also, I am thinking that there is not necessarily reason to rush to get it into the repo before they do.

And, sure I will reopen it. I wasn't sure about the rules, and it seemed like maybe it was a duplicate.

@nouritsu
Copy link
Copy Markdown
Contributor Author

nouritsu commented Apr 2, 2026

Yeah, I agree. Better to merge this only when the program is 100% usable.

@BirdeeHub
Copy link
Copy Markdown
Owner

BirdeeHub commented Apr 3, 2026

I mean... IMO it won't be 100% usable until we can specify the path to a font via an actual path and not just a name (like we can in wezterm, which is really nice for wrapping, although, to be fair, wezterm is the only one I know of which allows this)

So, 100% usable isn't necessary, but it would be nice if that particular bug were fixed first 🤣

But yeah if they fixed this bug and added that feature, I would switch to ghostty personally, just because I don't need 90% of terminal features anyway due to being a tmux user and it likely has better kitty graphics support. (I found out zellij has wasm plugins recently, and am interested... but tmux solves all my problems as-is, so, maybe someday I will check it out but not soon. We do have a wlib.toKdl now though.... which would be useful for zellij)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants