Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration using dynamically linked shared libraries #1358

Closed
LordMZTE opened this issue Jan 22, 2024 · 1 comment
Closed

Configuration using dynamically linked shared libraries #1358

LordMZTE opened this issue Jan 22, 2024 · 1 comment

Comments

@LordMZTE
Copy link
Collaborator

An approach I've seen many projects (such as rofi) take for plugins, which I'm a huge fan of, is loading dynamic libraries in a certain directory (could be the config dir for example).
Ghostty could utilize this as a way for advanced users to configure their terminal.

Why this makes sense

  1. Ghostty already has many of its types being C-compatible (for libghostty and the macOS apprt). This would mean that this is pretty low-effort to implement.
  2. Users may be more comfortable writing Zig or C than Ghostty's own configuration format. I myself had trouble staring at configuration lines that were giving me an error, unable to figure out why (yes, that's a separate problem, but the general point still holds :D).
  3. Keybinds could be given custom callbacks (function pointers) to do essentially anything.
  4. This would elegantly fix API for managing windows / tabs / splits #601 — such a config, or perhaps plugin is a better word, could implement some wire protocol, but that might not even be necessary depending on the use case.
  5. Microoptimization nuts like me will get a kick out of it :P

How to implement this

  1. Export relevant symbols and create headers (this is probably done already). A Zig client library could also be considered, but this isn't really a must.
  2. Discover plugins: search for dynamic library files (Linux: .so, Windows: .dll, macOS: no idea). This could just be the config directory, but also a subdirectory or somewhere entirely different.
  3. For each library - note that Zig has abstractions for both dlopen and dlsym (see: std.DynLib):
    • dlopen it (need to dlclose on shutdown)
    • Load and call some well-defined entry point symbol from it using dlsym. This could be ghostty_plugin_open, for example.
    • Plugins can now call into ghostty's API to do whatever.
@mitchellh
Copy link
Contributor

Thanks for writing this up. I think having this idea written somewhere will be useful.

More generally, I think this falls back onto a proposal to extend Ghostty. I don't think it's mutually exclusive to #601. #601 is a much lower bar to extending Ghostty, is more familiar to people from other terminals, etc. At the same time, the things you can do over a network API (even local) are going to be quite a bit different from a locally in-process dispatched function call. So I think this issue and that issue could co-exist if we decided to do both.

Also, I'd like to say that I'm a big fan of dlopen-ed plugins. They have their downsides (bugs in them can crash the hosting program) but they also have a ton of upsides like having very little performance penalty and as such being able to do a lot more that isn't quite possible with other plugin paradigms.

(FYI, I have a pretty significant background in plugin systems over the past 15 years or so. I developed in-process plugins with C, then in-process Ruby plugins for Vagrant, followed by RPC-based plugins for Go across a variety of high scale projects, and of course many of those projects also have network APIs. During that time, I've become well acquainted with the pros/cons of each approach. 😄 )

One thing that's particularly helpful for designing plugin APIs is having as many concrete use cases as possible. I.e. "I want to be able to do X which isn't possible today." By putting all of these together it becomes a lot easier to step back and see what the proper design approach is for a plugin system.

For now, let's consolidate any plugin discussion to #601 until I feel we're ready to spin this out.

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

No branches or pull requests

2 participants