498 lines
20 KiB
Markdown
498 lines
20 KiB
Markdown
# Contributing to Ghostty
|
|
|
|
This document describes the process of contributing to Ghostty. It is intended
|
|
for anyone considering opening an **issue**, **discussion** or **pull request**.
|
|
For people who are interested in developing Ghostty and technical details behind
|
|
it, please check out our ["Developing Ghostty"](HACKING.md) document as well.
|
|
|
|
> [!NOTE]
|
|
>
|
|
> I'm sorry for the wall of text. I'm not trying to be difficult and I do
|
|
> appreciate your contributions. Ghostty is a personal project for me that
|
|
> I maintain in my free time. If you're expecting me to dedicate my personal
|
|
> time to fixing bugs, maintaining features, and reviewing code, I do kindly
|
|
> ask you spend a few minutes reading this document. Thank you. ❤️
|
|
|
|
## AI Assistance Notice
|
|
|
|
> [!IMPORTANT]
|
|
>
|
|
> The Ghostty project allows AI-**assisted** _code contributions_, which
|
|
> must be properly disclosed in the pull request.
|
|
|
|
If you are using any kind of AI assistance while contributing to Ghostty,
|
|
**this must be disclosed in the pull request**, along with the extent to
|
|
which AI assistance was used (e.g. docs only vs. code generation).
|
|
|
|
The submitter must have also tested the pull request on all impacted
|
|
platforms, and it's **highly discouraged** to code for an unfamiliar platform
|
|
with AI assistance alone: if you only have a macOS machine, do **not** ask AI
|
|
to write the equivalent GTK code, and vice versa — someone else with more
|
|
expertise will eventually get to it and do it for you.
|
|
|
|
> [!WARNING]
|
|
> **Note that AI _assistance_ does not equal AI _generation_**. We require
|
|
> a significant amount of human accountability, involvement and interaction
|
|
> even within AI-assisted contributions. Contributors are required to be able
|
|
> to understand the AI-assisted output, reason with it and answer critical
|
|
> questions about it. Should a PR see no visible human accountability and
|
|
> involvement, or it is so broken that it requires significant rework to be
|
|
> acceptable, **we reserve the right to close it without hesitation**.
|
|
|
|
**In addition, we currently restrict AI assistance to code changes only.**
|
|
No AI-generated media, e.g. artwork, icons, videos and other assets is
|
|
allowed, as it goes against the methodology and ethos behind Ghostty.
|
|
While AI-assisted code can help with productive prototyping, creative
|
|
inspiration and even automated bugfinding, we have currently found zero
|
|
benefit to AI-generated assets. Instead, we are far more interested and
|
|
invested in funding professional work done by human designers and artists.
|
|
If you intend to submit AI-generated assets to Ghostty, sorry,
|
|
we are not interested.
|
|
|
|
Likewise, all community interactions, including all comments on issues and
|
|
discussions and all PR titles and descriptions **must be composed by a human**.
|
|
Community moderators and Ghostty maintainers reserve the right to mark
|
|
AI-generated responses as spam or disruptive content, and ban users who have
|
|
been repeatedly caught relying entirely on LLMs during interactions.
|
|
|
|
> [!NOTE]
|
|
> If your English isn't the best and you are currently relying on an LLM to
|
|
> translate your responses, don't fret — usually we maintainers will be able
|
|
> to understand your messages well enough. We'd like to encourage real humans
|
|
> to interact with each other more, and the positive impact of genuine,
|
|
> responsive yet imperfect human interaction more than makes up for any
|
|
> language barrier.
|
|
>
|
|
> Please write your responses yourself, to the best of your ability.
|
|
> If you do feel the need to polish your sentences, however, please use
|
|
> dedicated translation software rather than an LLM.
|
|
>
|
|
> We greatly appreciate it. Thank you. ❤️
|
|
|
|
Minor exceptions to this policy include trivial AI-generated tab completion
|
|
functionality, as it usually does not impact the quality of the code and
|
|
do not need to be disclosed, and commit titles and messages, which are often
|
|
generated by AI coding agents.
|
|
|
|
An example disclosure:
|
|
|
|
> This PR was written primarily by Claude Code.
|
|
|
|
Or a more detailed disclosure:
|
|
|
|
> I consulted ChatGPT to understand the codebase but the solution
|
|
> was fully authored manually by myself.
|
|
|
|
An example of a **problematic** disclosure (not having tested all platforms):
|
|
|
|
> I used Amp to code both macOS and GTK UIs, but I have not yet tested
|
|
> the GTK UI as I don't have a Linux setup.
|
|
|
|
Failure to disclose this is first and foremost rude to the human operators
|
|
on the other end of the pull request, but it also makes it difficult to
|
|
determine how much scrutiny to apply to the contribution.
|
|
|
|
In a perfect world, AI assistance would produce equal or higher quality
|
|
work than any human. That isn't the world we live in today, and in most cases
|
|
it's generating slop. I say this despite being a fan of and using them
|
|
successfully myself (with heavy supervision)!
|
|
|
|
Please be respectful to maintainers and disclose AI assistance.
|
|
|
|
## Quick Guide
|
|
|
|
### I'd like to contribute
|
|
|
|
[All issues are actionable](#issues-are-actionable). Pick one and start
|
|
working on it. Thank you. If you need help or guidance, comment on the issue.
|
|
Issues that are extra friendly to new contributors are tagged with
|
|
["contributor friendly"].
|
|
|
|
["contributor friendly"]: https://github.com/ghostty-org/ghostty/issues?q=is%3Aissue%20is%3Aopen%20label%3A%22contributor%20friendly%22
|
|
|
|
### I'd like to translate Ghostty to my language
|
|
|
|
We have written a [Translator's Guide](po/README_TRANSLATORS.md) for
|
|
everyone interested in contributing translations to Ghostty.
|
|
Translations usually do not need to go through the process of issue triage
|
|
and you can submit pull requests directly, although please make sure that
|
|
our [Style Guide](po/README_TRANSLATORS.md#style-guide) is followed before
|
|
submission.
|
|
|
|
### I have a bug! / Something isn't working
|
|
|
|
First, search the issue tracker and discussions for similar issues. Tip: also
|
|
search for [closed issues] and [discussions] — your issue might have already
|
|
been fixed!
|
|
|
|
> [!NOTE]
|
|
>
|
|
> If there is an _open_ issue or discussion that matches your problem,
|
|
> **please do not comment on it unless you have valuable insight to add**.
|
|
>
|
|
> GitHub has a very _noisy_ set of default notification settings which
|
|
> sends an email to _every participant_ in an issue/discussion every time
|
|
> someone adds a comment. Instead, use the handy upvote button for discussions,
|
|
> and/or emoji reactions on both discussions and issues, which are a visible
|
|
> yet non-disruptive way to show your support.
|
|
|
|
If your issue hasn't been reported already, open an ["Issue Triage"] discussion
|
|
and make sure to fill in the template **completely**. They are vital for
|
|
maintainers to figure out important details about your setup.
|
|
|
|
> [!WARNING]
|
|
>
|
|
> A _very_ common mistake is to file a bug report either as a Q&A or a Feature
|
|
> Request. **Please don't do this.** Otherwise, maintainers would have to ask
|
|
> for your system information again manually, and sometimes they will even ask
|
|
> you to create a new discussion because of how few detailed information is
|
|
> required for other discussion types compared to Issue Triage.
|
|
>
|
|
> Because of this, please make sure that you _only_ use the "Issue Triage"
|
|
> category for reporting bugs — thank you!
|
|
|
|
[closed issues]: https://github.com/ghostty-org/ghostty/issues?q=is%3Aissue%20state%3Aclosed
|
|
[discussions]: https://github.com/ghostty-org/ghostty/discussions?discussions_q=is%3Aclosed
|
|
["Issue Triage"]: https://github.com/ghostty-org/ghostty/discussions/new?category=issue-triage
|
|
|
|
### I have an idea for a feature
|
|
|
|
Like bug reports, first search through both issues and discussions and try to
|
|
find if your feature has already been requested. Otherwise, open a discussion
|
|
in the ["Feature Requests, Ideas"] category.
|
|
|
|
["Feature Requests, Ideas"]: https://github.com/ghostty-org/ghostty/discussions/new?category=feature-requests-ideas
|
|
|
|
### I've implemented a feature
|
|
|
|
1. If there is an issue for the feature, open a pull request straight away.
|
|
2. If there is no issue, open a discussion and link to your branch.
|
|
3. If you want to live dangerously, open a pull request and
|
|
[hope for the best](#pull-requests-implement-an-issue).
|
|
|
|
### I have a question which is neither a bug report nor a feature request
|
|
|
|
Open an [Q&A discussion], or join our [Discord Server] and ask away in the
|
|
`#help` forum channel.
|
|
|
|
Do not use the `#terminals` or `#development` channels to ask for help —
|
|
those are for general discussion about terminals and Ghostty development
|
|
respectively. If you do ask a question there, you will be redirected to
|
|
`#help` instead.
|
|
|
|
> [!NOTE]
|
|
> If your question is about a missing feature, please open a discussion under
|
|
> the ["Feature Requests, Ideas"] category. If Ghostty is behaving
|
|
> unexpectedly, use the ["Issue Triage"] category.
|
|
>
|
|
> The "Q&A" category is strictly for other kinds of discussions and do not
|
|
> require detailed information unlike the two other categories, meaning that
|
|
> maintainers would have to spend the extra effort to ask for basic information
|
|
> if you submit a bug report under this category.
|
|
>
|
|
> Therefore, please **pay attention to the category** before opening
|
|
> discussions to save us all some time and energy. Thank you!
|
|
|
|
[Q&A discussion]: https://github.com/ghostty-org/ghostty/discussions/new?category=q-a
|
|
[Discord Server]: https://discord.gg/ghostty
|
|
|
|
## General Patterns
|
|
|
|
### Issues are Actionable
|
|
|
|
The Ghostty [issue tracker](https://github.com/ghostty-org/ghostty/issues)
|
|
is for _actionable items_.
|
|
|
|
Unlike some other projects, Ghostty **does not use the issue tracker for
|
|
discussion or feature requests**. Instead, we use GitHub
|
|
[discussions](https://github.com/ghostty-org/ghostty/discussions) for that.
|
|
Once a discussion reaches a point where a well-understood, actionable
|
|
item is identified, it is moved to the issue tracker. **This pattern
|
|
makes it easier for maintainers or contributors to find issues to work on
|
|
since _every issue_ is ready to be worked on.**
|
|
|
|
If you are experiencing a bug and have clear steps to reproduce it, please
|
|
open an issue. If you are experiencing a bug but you are not sure how to
|
|
reproduce it or aren't sure if it's a bug, please open a discussion.
|
|
If you have an idea for a feature, please open a discussion.
|
|
|
|
### Pull Requests Implement an Issue
|
|
|
|
Pull requests should be associated with a previously accepted issue.
|
|
**If you open a pull request for something that wasn't previously discussed,**
|
|
it may be closed or remain stale for an indefinite period of time. I'm not
|
|
saying it will never be accepted, but the odds are stacked against you.
|
|
|
|
Issues tagged with "feature" represent accepted, well-scoped feature requests.
|
|
If you implement an issue tagged with feature as described in the issue, your
|
|
pull request will be accepted with a high degree of certainty.
|
|
|
|
> [!NOTE]
|
|
>
|
|
> **Pull requests are NOT a place to discuss feature design.** Please do
|
|
> not open a WIP pull request to discuss a feature. Instead, use a discussion
|
|
> and link to your branch.
|
|
|
|
# Developer Guide
|
|
|
|
> [!NOTE]
|
|
>
|
|
> **The remainder of this file is dedicated to developers actively
|
|
> working on Ghostty.** If you're a user reporting an issue, you can
|
|
> ignore the rest of this document.
|
|
|
|
## Including and Updating Translations
|
|
|
|
See the [Contributor's Guide](po/README_CONTRIBUTORS.md) for more details.
|
|
|
|
## Checking for Memory Leaks
|
|
|
|
While Zig does an amazing job of finding and preventing memory leaks,
|
|
Ghostty uses many third-party libraries that are written in C. Improper usage
|
|
of those libraries or bugs in those libraries can cause memory leaks that
|
|
Zig cannot detect by itself.
|
|
|
|
### On Linux
|
|
|
|
On Linux the recommended tool to check for memory leaks is Valgrind. The
|
|
recommended way to run Valgrind is via `zig build`:
|
|
|
|
```sh
|
|
zig build run-valgrind
|
|
```
|
|
|
|
This builds a Ghostty executable with Valgrind support and runs Valgrind
|
|
with the proper flags to ensure we're suppressing known false positives.
|
|
|
|
You can combine the same build args with `run-valgrind` that you can with
|
|
`run`, such as specifying additional configurations after a trailing `--`.
|
|
|
|
## Input Stack Testing
|
|
|
|
The input stack is the part of the codebase that starts with a
|
|
key event and ends with text encoding being sent to the pty (it
|
|
does not include _rendering_ the text, which is part of the
|
|
font or rendering stack).
|
|
|
|
If you modify any part of the input stack, you must manually verify
|
|
all the following input cases work properly. We unfortunately do
|
|
not automate this in any way, but if we can do that one day that'd
|
|
save a LOT of grief and time.
|
|
|
|
Note: this list may not be exhaustive, I'm still working on it.
|
|
|
|
### Linux IME
|
|
|
|
IME (Input Method Editors) are a common source of bugs in the input stack,
|
|
especially on Linux since there are multiple different IME systems
|
|
interacting with different windowing systems and application frameworks
|
|
all written by different organizations.
|
|
|
|
The following matrix should be tested to ensure that all IME input works
|
|
properly:
|
|
|
|
1. Wayland, X11
|
|
2. ibus, fcitx, none
|
|
3. Dead key input (e.g. Spanish), CJK (e.g. Japanese), Emoji, Unicode Hex
|
|
4. ibus versions: 1.5.29, 1.5.30, 1.5.31 (each exhibit slightly different behaviors)
|
|
|
|
> [!NOTE]
|
|
>
|
|
> This is a **work in progress**. I'm still working on this list and it
|
|
> is not complete. As I find more test cases, I will add them here.
|
|
|
|
#### Dead Key Input
|
|
|
|
Set your keyboard layout to "Spanish" (or another layout that uses dead keys).
|
|
|
|
1. Launch Ghostty
|
|
2. Press `'`
|
|
3. Press `a`
|
|
4. Verify that `á` is displayed
|
|
|
|
Note that the dead key may or may not show a preedit state visually.
|
|
For ibus and fcitx it does but for the "none" case it does not. Importantly,
|
|
the text should be correct when it is sent to the pty.
|
|
|
|
We should also test canceling dead key input:
|
|
|
|
1. Launch Ghostty
|
|
2. Press `'`
|
|
3. Press escape
|
|
4. Press `a`
|
|
5. Verify that `a` is displayed (no diacritic)
|
|
|
|
#### CJK Input
|
|
|
|
Configure fcitx or ibus with a keyboard layout like Japanese or Mozc. The
|
|
exact layout doesn't matter.
|
|
|
|
1. Launch Ghostty
|
|
2. Press `Ctrl+Shift` to switch to "Hiragana"
|
|
3. On a US physical layout, type: `konn`, you should see `こん` in preedit.
|
|
4. Press `Enter`
|
|
5. Verify that `こん` is displayed in the terminal.
|
|
|
|
We should also test switching input methods while preedit is active, which
|
|
should commit the text:
|
|
|
|
1. Launch Ghostty
|
|
2. Press `Ctrl+Shift` to switch to "Hiragana"
|
|
3. On a US physical layout, type: `konn`, you should see `こん` in preedit.
|
|
4. Press `Ctrl+Shift` to switch to another layout (any)
|
|
5. Verify that `こん` is displayed in the terminal as committed text.
|
|
|
|
## Nix Virtual Machines
|
|
|
|
Several Nix virtual machine definitions are provided by the project for testing
|
|
and developing Ghostty against multiple different Linux desktop environments.
|
|
|
|
Running these requires a working Nix installation, either Nix on your
|
|
favorite Linux distribution, NixOS, or macOS with nix-darwin installed. Further
|
|
requirements for macOS are detailed below.
|
|
|
|
VMs should only be run on your local desktop and then powered off when not in
|
|
use, which will discard any changes to the VM.
|
|
|
|
The VM definitions provide minimal software "out of the box" but additional
|
|
software can be installed by using standard Nix mechanisms like `nix run nixpkgs#<package>`.
|
|
|
|
### Linux
|
|
|
|
1. Check out the Ghostty source and change to the directory.
|
|
2. Run `nix run .#<vmtype>`. `<vmtype>` can be any of the VMs defined in the
|
|
`nix/vm` directory (without the `.nix` suffix) excluding any file prefixed
|
|
with `common` or `create`.
|
|
3. The VM will build and then launch. Depending on the speed of your system, this
|
|
can take a while, but eventually you should get a new VM window.
|
|
4. The Ghostty source directory should be mounted to `/tmp/shared` in the VM. Depending
|
|
on what UID and GID of the user that you launched the VM as, `/tmp/shared` _may_ be
|
|
writable by the VM user, so be careful!
|
|
|
|
### macOS
|
|
|
|
1. To run the VMs on macOS you will need to enable the Linux builder in your `nix-darwin`
|
|
config. This _should_ be as simple as adding `nix.linux-builder.enable=true` to your
|
|
configuration and then rebuilding. See [this](https://nixcademy.com/posts/macos-linux-builder/)
|
|
blog post for more information about the Linux builder and how to tune the performance.
|
|
2. Once the Linux builder has been enabled, you should be able to follow the Linux instructions
|
|
above to launch a VM.
|
|
|
|
### Custom VMs
|
|
|
|
To easily create a custom VM without modifying the Ghostty source, create a new
|
|
directory, then create a file called `flake.nix` with the following text in the
|
|
new directory.
|
|
|
|
```
|
|
{
|
|
inputs = {
|
|
nixpkgs.url = "nixpkgs/nixpkgs-unstable";
|
|
ghostty.url = "github:ghostty-org/ghostty";
|
|
};
|
|
outputs = {
|
|
nixpkgs,
|
|
ghostty,
|
|
...
|
|
}: {
|
|
nixosConfigurations.custom-vm = ghostty.create-gnome-vm {
|
|
nixpkgs = nixpkgs;
|
|
system = "x86_64-linux";
|
|
overlay = ghostty.overlays.releasefast;
|
|
# module = ./configuration.nix # also works
|
|
module = {pkgs, ...}: {
|
|
environment.systemPackages = [
|
|
pkgs.btop
|
|
];
|
|
};
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
The custom VM can then be run with a command like this:
|
|
|
|
```
|
|
nix run .#nixosConfigurations.custom-vm.config.system.build.vm
|
|
```
|
|
|
|
A file named `ghostty.qcow2` will be created that is used to persist any changes
|
|
made in the VM. To "reset" the VM to default delete the file and it will be
|
|
recreated the next time you run the VM.
|
|
|
|
### Contributing new VM definitions
|
|
|
|
#### VM Acceptance Criteria
|
|
|
|
We welcome the contribution of new VM definitions, as long as they meet the following criteria:
|
|
|
|
1. They should be different enough from existing VM definitions that they represent a distinct
|
|
user (and developer) experience.
|
|
2. There's a significant Ghostty user population that uses a similar environment.
|
|
3. The VMs can be built using only packages from the current stable NixOS release.
|
|
|
|
#### VM Definition Criteria
|
|
|
|
1. VMs should be as minimal as possible so that they build and launch quickly.
|
|
Additional software can be added at runtime with a command like `nix run nixpkgs#<package name>`.
|
|
2. VMs should not expose any services to the network, or run any remote access
|
|
software like SSH daemons, VNC or RDP.
|
|
3. VMs should auto-login using the "ghostty" user.
|
|
|
|
## Nix VM Integration Tests
|
|
|
|
Several Nix VM tests are provided by the project for testing Ghostty in a "live"
|
|
environment rather than just unit tests.
|
|
|
|
Running these requires a working Nix installation, either Nix on your
|
|
favorite Linux distribution, NixOS, or macOS with nix-darwin installed. Further
|
|
requirements for macOS are detailed below.
|
|
|
|
### Linux
|
|
|
|
1. Check out the Ghostty source and change to the directory.
|
|
2. Run `nix run .#check.<system>.<test-name>.driver`. `<system>` should be
|
|
`x86_64-linux` or `aarch64-linux` (even on macOS, this launches a Linux
|
|
VM, not a macOS one). `<test-name>` should be one of the tests defined in
|
|
`nix/tests.nix`. The test will build and then launch. Depending on the speed
|
|
of your system, this can take a while. Eventually though the test should
|
|
complete. Hopefully successfully, but if not error messages should be printed
|
|
out that can be used to diagnose the issue.
|
|
3. To run _all_ of the tests, run `nix flake check`.
|
|
|
|
### macOS
|
|
|
|
1. To run the VMs on macOS you will need to enable the Linux builder in your `nix-darwin`
|
|
config. This _should_ be as simple as adding `nix.linux-builder.enable=true` to your
|
|
configuration and then rebuilding. See [this](https://nixcademy.com/posts/macos-linux-builder/)
|
|
blog post for more information about the Linux builder and how to tune the performance.
|
|
2. Once the Linux builder has been enabled, you should be able to follow the Linux instructions
|
|
above to launch a test.
|
|
|
|
### Interactively Running Test VMs
|
|
|
|
To run a test interactively, run `nix run
|
|
.#check.<system>.<test-name>.driverInteractive`. This will load a Python console
|
|
that can be used to manage the test VMs. In this console run `start_all()` to
|
|
start the VM(s). The VMs should boot up and a window should appear showing the
|
|
VM's console.
|
|
|
|
For more information about the Nix test console, see [the NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-call-nixos-test-outside-nixos)
|
|
|
|
### SSH Access to Test VMs
|
|
|
|
Some test VMs are configured to allow outside SSH access for debugging. To
|
|
access the VM, use a command like the following:
|
|
|
|
```
|
|
ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null -p 2222 root@192.168.122.1
|
|
ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null -p 2222 ghostty@192.168.122.1
|
|
```
|
|
|
|
The SSH options are important because the SSH host keys will be regenerated
|
|
every time the test is started. Without them, your personal SSH known hosts file
|
|
will become difficult to manage. The port that is needed to access the VM may
|
|
change depending on the test.
|
|
|
|
None of the users in the VM have passwords so do not expose these VMs to the Internet.
|