HackerTrans
TopNewTrendsCommentsPastAskShowJobs

Ghostel.el: Terminal emulator powered by libghostty(dakra.github.io)

267 points·by signa11·19 ชั่วโมงที่ผ่านมา·52 comments
dakra.github.io
Ghostel.el: Terminal emulator powered by libghostty

https://dakra.github.io/ghostel/

55 comments

dakra·14 ชั่วโมงที่ผ่านมา
Hi! Maintainer of Ghostel here.

baokaola and I actually wanted to do a "Show HN" next week, but looks like someone was faster submitting the link.

Have a look at the GitHub repo which is a bit nicer for a quick overview: https://github.com/dakra/ghostel

To add some context, Ghostel is a terminal emulator for Emacs powered by libghostty-vt.

There's a feature comparison vs vterm and eat: https://dakra.github.io/ghostel/#ghostel-vs-vterm

And here is a gist with images to compare performance and correctness: https://gist.github.com/dakra/4a0b76ebcf5d52338e134864378465...

But for me personally, it has not only replaced vterm/eat but also any other external terminal like kitty/Ghostty.

Having your terminal text just like a normal Emacs buffer opens up so many possibilities and extension points that are just not available on any other terminal.

Even simple stuff like searching in the scrollback, then navigating and selecting+copying a paragraph only with the keyboard. For every Emacs user that's so natural and fast in Ghostel while often cumbersome in other Terminals where I just reach to the mouse because it's easier.

Happy to answer any questions and also like to hear feedback positive or negative.

If you're an Emacs user and tried Ghostel and are still using Ghostty (or another external Terminal), is there something Ghostel is missing or is it just because you want some processes to run outside of Emacs?

baokaola and I are also very active on GitHub, so feel free to open an issue if you have any.
aardvark179·10 ชั่วโมงที่ผ่านมา
I think the thing that stops me from running more processes inside emacs is that a large diff parse from magit or similar can block everything, and so I end up keeping a separate terminal around anyway.
mort96·9 ชั่วโมงที่ผ่านมา
Huh is that true? Does running a command in a terminal buffer block all of EMacs? That's extremely surprising, the main use of these kinds of integrated terminals for me is to compile and run which means long running commands. Is this use case fundamentally not supported due to EMacs's architecture?
aardvark179·8 ชั่วโมงที่ผ่านมา
No, running a command in a terminal buffer doesn’t block the emacs UI, but a long running bit of elisp running in emacs can block the UI.
b3n·12 ชั่วโมงที่ผ่านมา
Hi dakra!

> is there something Ghostel is missing

eshell allows me to manipulate text as I would in any other Emacs buffer. If I have a function which wraps a word in quotes, and bind it to a key, I can be confident it will work in eshell like it does anywhere else. It's a real killer feature. If I use evil-mode, or xah-fly-keys, or simply want to use ispell to correct the spelling of a word, it all works.

Unfortunately with Ghostel none of this works. It's not integrated in the same way. There are extensions like evil-ghostel-mode, but they are limited.

Are there any plans to improve this, or is it a limitation Ghostel has to live with?

A Ghostel equivalent of eat-eshell-mode would be amazing.
dakra·12 ชั่วโมงที่ผ่านมา
Did you see ghostel line-mode? This basically gives you a `M-x shell` experience where everything is a buffer and nothing is send to the terminal until you press enter.

There you could type on the prompt line and then call jinx or your quote wrapping function etc as it's just a normal Emacs buffer. You can't edit the scrollback buffer though, but I don't think that's possible in eshell either.

But line-mode has it's own set of problems. Since we don't send anything to the shell, you could have some problems with autocomplete or similar things that change the text depending on each typed char. Similarly we automatically disable line-mode when you enter a TUI (alt-screen) app, as line-mode doesn't make too much sense in e.g. vim. But that's configurable and you can still force line-mode, it really depends on the TUI apps.

We try to support as much as possible and work around things like fish autocomplete etc. But please try and report any issues you find.
accelbred·10 ชั่วโมงที่ผ่านมา
Editing scrollback is possible in eshell, and something I use often.
dakra·10 ชั่วโมงที่ผ่านมา
Ah. I tested it before but now I see that I have `(setq eshell-scroll-to-bottom-on-input 'all)` in my config which always snapped point back to the prompt when I tried to edit the scrollback.

Anyway, unfortunately that is not possible in a Ghostel buffer and most likely also will never be. I'm open to ideas though how we could improve or replicate your eshell workflow.

But also, eshell is awesome and Ghostel is not a replacement for it. It's more a replacement for term.el, maybe shell.el (with line-mode) and other terminal packages like eat and vterm.
MarsIronPI·9 ชั่วโมงที่ผ่านมา
I think issue #426[0] would be sufficient, since it would allow for editing after the command is finished. I understand that it probably won't happen any time soon, but embedding a full terminal emulator in Eshell is the thing that's got me staying on EAT right now.

Ghostel looks really nice though!

[0]: https://github.com/dakra/ghostel/issues/426
dakra·7 ชั่วโมงที่ผ่านมา
Noted.

I didn't even think of the use-case that then you can edit output from finished commands in the scrollback. But it makes sense and is another +1 for that feature request.
xoxolian·4 ชั่วโมงที่ผ่านมา
Yeah, Ghostel works great for me so far!

Two things: - defined f1 to toggle between semi-char vs copy modes - I ask myself "Is it ok if Emacs dies or I nuke it?" If not, then I execute a command in the normal terminal
arikrahman·11 ชั่วโมงที่ผ่านมา
Howdy,

Awesome project. Been using with doom for a while. How do you manage to get scrolling programs to work (eg Lazygit or Reasonix) where other emulators fail? Is it something special in your implentation or library that makes this work?
baokaola·8 ชั่วโมงที่ผ่านมา
Are you thinking about using the scroll wheel of the mouse to scroll within the program? If the appropriate terminal modes are enabled by the application running in the terminal, we capture the scroll events in Emacs and forward them to the terminal instead of letting Emacs handle them.
helibom·7 ชั่วโมงที่ผ่านมา
Wish it had the pattern based Quick-select mode from WezTerm. Since I discovered that I never want to use another term.
dakra·6 ชั่วโมงที่ผ่านมา
You have the full power of Emacs to your disposal.

I have never used WezTerm but from a quick look, it seems you can quickly copy text ace-jump style.

In Emacs you could use e.g. avy to do the same, but there is probably a bunch of other similar packages that do the same.

And additionally you're not restricted to just select/copy a word. You can freely move around and use e.g. expand-region or similar to quickly select more.

It's Emacs after all, the possibilities are endless ;)
sigbottle·12 ชั่วโมงที่ผ่านมา
How was integration for you guys? Was the integration easier for you guys since you have an established emacs system consuming terminal output with reasoned semantics over what goes where for existing subsystems (rendering, osc codes, etc)?

For libghostty-vt, since you're targeting a terminal TUI instead of an external subsystem (for example; for ghostty, you hit libghostty-vt -> GPU rendering, which is external), you still have to buy into terminal semantics. in my experience, since I was trying to replicate mosh with libghostty-vt as the parser, what happened was that my optimized re-rendering kept getting increasingly coupled to terminal semantics (and the UDP state update model too), otherwise I'd have to send the entire terminal grid over the network like, every time.

What are the tricks for making this both performant and not like, utter cancer? You have a harder issue here too (similar to tmux) in that certain optimizations are just not available to you, or you have to translate (literally geometrically) certain instructions
baokaola·12 ชั่วโมงที่ผ่านมา
I'm not entirely sure what you're asking. But I'll answer to the best of my abilities:

For Ghostel, libghostty-vt is the source of truth and the architecture is essentially that we serve input to the PTY and the PTY serves output to libghostty-vt which builds out the state in the form of a terminal screen structure. The goal is then to keep the contents of an Emacs buffer up to date to this terminal screen without replace the entire thing every time we redraw. We make use of mainly two things in order to do as little work as possible: - Scrollback is immutable and thus never has to be modified unless it's evicted, alt screen is activated, dimensions change etc. - libghostty-vt maintains row level dirty flags that we scan to make sure we're only replacing lines that have actually changed.

So for the rendering part, we're only diffing the grid state against the buffer, not doing anything based on terminal semantics per se, parser events that draw to the screen are passed straight to the terminal handler. But of course, certain things we need to hook into such as directory and title changes, of clipboard events etc.

Might also add that we're using the direct Zig API, not the C API, which means we have access to things that aren't exposed in the C API.
nihsett·18 นาทีที่ผ่านมา
Does ghostty have any features that makes it better than kitty in anyway? I keep seeing this all over the place, but I still don't understand why it's better than existing options.

Can someone help who's used both help me, what's the elevator pitch for this, why is it worth checking out?
LtdJorge·12 ชั่วโมงที่ผ่านมา
I think the title should mention Emacs somewhere. A terminal emulator is different than a terminal emulator for Emacs.
dakra·12 ชั่วโมงที่ผ่านมา
I agree.

And I would also prefer if the link went to https://github.com/dakra/ghostel instead of the documentation which is not that helpful if you don't know what the project is.
canthonytucci·11 ชั่วโมงที่ผ่านมา
.el = emacslisp file extension
lucasoshiro·9 ชั่วโมงที่ผ่านมา
I know this only because I'm an emacs user. Outside that niche .el is an obscure file extension, so, no, it's not that obvious
Brian_K_White·6 ชั่วโมงที่ผ่านมา
If you say so. I didn't know that, which supports the suggestion that the title fails to be meaningful.

It's not the same as expecting the reader to know what a terminal is, just in case anyone was thinking of going there next.
iLemming·6 ชั่วโมงที่ผ่านมา
> the title fails to be meaningful

It's a weird flex to insist that the titles should always be extremely descriptive. It is already meaningful for the respected audience. Otherwise you can endlessly argue that a florist may not understand what "terminal" and "emulator" are, therefore it should be more descriptive for an occasional florist vising HN. For anyone who doesn't know what .el stands for, they'd click, see it's about Emacs and if not interested - close the tab and forget about it. Takes maybe a second. Not even a smallest imaginable deal - not big at all.
jdormit·15 ชั่วโมงที่ผ่านมา
I recently switched from vterm to ghostel, and it is generally much, much better - noticeably faster (e.g. fancy TUI apps that try to refresh the whole terminal every frame actually work), more reliable input handling, and a nicer ELisp API.

That being said, there are still some rough edges. Sometimes it fails to properly clear the terminal, leaving junk at the top of the buffer before the currrent prompt line. And on a couple of occasions it has totally frozen, with no fix other than killing the buffer and starting over.

Overall, it’s very promising and totally usable as a daily driver, but it needs a bit of polish and bug fixes before I would consider it mature.
baokaola·14 ชั่วโมงที่ผ่านมา
Ghostel co-maintainer here: Understand if you don't have a repro, but if you ever have something actionable we'd love it if you filed an issue, or have the information get to us some other way.

The junk at the top of the screen sounds like it could be https://github.com/dakra/ghostel/issues/495 and it should be fixed on later versions. But maybe you're seeing another bug. The tricky part is replicating the libghostty-vt internal data into an Emacs buffer while only replacing the parts that need to be replaced. We have property based tests to exercise this a lot, but sometimes things slip through.

The latest released version as I'm writing this should have improved lifecycle handling, so maybe it also fixes some of your issues.

As you say, the project is still in the early phase so hopefully, we can iron things out over time.
pingisland·13 ชั่วโมงที่ผ่านมา
I also switched from vterm and ghostel is much more responsive for me. Thanks for maintaining it! I use it everyday.

I do see a similar issue, where when I switch to the ghostel buffer and it wasn’t visible before, the text is scrambled. I’ll check if I can find a way to reliably reproduce it.
baokaola·12 ชั่วโมงที่ผ่านมา
This is a known issue that I've been chasing myself. It most likely has to do with the fact that we cannot render hidden buffers (for reasons) so when the buffer reappears again, we have hooks to refresh it. But sometimes it fails to refresh fully.

When are you mostly seeing this? With agent TUIs?
jdormit·10 ชั่วโมงที่ผ่านมา
> The junk at the top of the screen sounds like it could be https://github.com/dakra/ghostel/issues/495 and it should be fixed on later versions

Yes, that sounds like the same issue. I’ll update to the latest version and see if it’s resolved. And thanks for your work on this package, it’s been a real game-changer for me!
Ferret7446·51 นาทีที่ผ่านมา
Downloading a compiled module is a huge negative in the age of supply chain attacks; you're begging to get compromised.
guskel·6 ชั่วโมงที่ผ่านมา
Thank you so much for building this. I've been wanting something just like this and I'm trying it now and it's amazing. I was struggling with vterm and now this might become my daily driver.
iLemming·5 ชั่วโมงที่ผ่านมา
It's legit nice. I have gone through vterm -> eat -> ghostel transition and this is a winner. At least for now.
iLemming·5 ชั่วโมงที่ผ่านมา
It would be nice to have some practical examples of how efficiently use its different input modes. On the surface the reasoning is straightforward - a terminal wants every keystroke. The editor also wants keystrokes for its own commands. These two desires are irreconcilable, so any editor-embedded terminal must have a way to switch "who owns the keyboard." That switch is a mode. There is no escaping it.

But like people coming to Emacs from Neovim may get confused why is nvim +term has only two modes, but this one has 5, what's the point? Without clearly understanding the problem, the knee-jerk reaction might be "this thing is an over-engineered BS", while in truth Ghostel isn't more complex because it's over-engineered - it's more complex because it solves more of the problem - the extra modes are opt-in tools for tasks nvim simply doesn't address. But it's not super clear how in practice use that leverage efficently.
varjag·12 ชั่วโมงที่ผ่านมา
Been using it for bit over a month now. It's really nice that you can click on code references in Codex summaries and open them right there in Emacs buffers.
dakra·8 ชั่วโมงที่ผ่านมา
And not only mouse click of course, but you can use `ghostel-previous-hyperlink` (or ghostel-next-hyperlink) to quickly jump to the last hyperlink displayed.

It also installs a repeat-mode map, so if you see 3 url or file links as output you can just `C-c C-p p p RET` and it will open the first link.

I use that feature all the time.
KallDrexx·14 ชั่วโมงที่ผ่านมา
I came across this the other day and it's come close to helping me make the switch to emacs.

I've been de-IDEing myself lately for a variety of reasons. I've been trying to figure out if my future is tmux + neovim or emacs.

I got setup most of the way with vanilla neovim and customizing to my liking pretty easy.

I like the ideas of emacs and there are things that are compelling, but oh man it feels imprenetable, especially with how easy I was able to get up and running with neovim.
aftergibson·14 ชั่วโมงที่ผ่านมา
This is working great, it plus the Claude code integration has really adjusted how much I use Emacs. It's become a bit of a hub for me now.
4b11b4·10 ชั่วโมงที่ผ่านมา
What do you mean by integration. Do you have a model driving emacs via server?
baokaola·8 ชั่วโมงที่ผ่านมา
Maybe he's talking about claude-code-ide.el which piggybacks on Claude Code's IDE integration. It recently added support for Ghostel too.
parentheses·11 ชั่วโมงที่ผ่านมา
Ghostty has crashed nightly for me with ~10 terminals open across a few windows. So, I haven't been able to run it nor would I want to embed it inside anything I daily drive.
adrian_b·11 ชั่วโมงที่ผ่านมา
I am running Ghostty 1.1.3, on Gentoo Linux.

I have opened right now about a dozen Ghostty windows and about 20 tabs in each window, i.e. more than 100 shell instances.

I have started in as many of them as I could, before becoming too bored, a "ls -lR" on a file system with many millions of files.

I could not see any problem, much less any crash. I have been using Ghostty for a few months, very intensively, all day long, and I have not seen any crash or other suspicious behavior.

If you have seen a crash, perhaps there was either some specific version of Ghosstty that had a bug, or, more likely, some weird interaction with some other software that you have, and which might be buggy, e.g. the GPU driver. (I am using an NVIDIA GPU.)
coffeeindex·10 ชั่วโมงที่ผ่านมา
Just commenting to say I've had the same experience. Been using Ghostty since (I was aware of) its release and it has been buttery smooth ever since. I occasionally see people talking about crashing or other issues they've had with Ghostty but I've not seen anything of the sort.
vinniepukh·11 ชั่วโมงที่ผ่านมา
cool story bro. feel free to make a github issue. I've been daily-driving Ghostty for years and i don't remember the last time it crashed on me.
ivanjermakov·13 ชั่วโมงที่ผ่านมา
> The native module is a prebuilt binary that auto-downloads on first use

Why? Keep it a part of distribution.
dakra·13 ชั่วโมงที่ผ่านมา
That's because MELPA (and ELPA) doesn't have a way to attach platform specific files. It's all just git checkouts.

That means we would have to check in the module binary for all platforms (>10MB together) if we want that it comes with the distribution.

Also looking at e.g. jinx, another popular package that uses Emacs native modules, it does it like vterm and offers to compile on first usage.

So as a Emacs package author, for a user friendly installation you can realistically only offer to download or compile on first use.
vijucat·12 ชั่วโมงที่ผ่านมา
Question: if I don't use TUIs or millions of lines of scrolling text, what am I missing by not using these newer terminal implementations? I use mintty on Windows and am pretty happy with it.
ireadmevs·10 ชั่วโมงที่ผ่านมา
For me is the ability to maintain the same keyboard workflow, no matter if I’m dealing with files or terminal (switching buffers, navigating/searching/selecting/copying/pasting text, etc.), I get to keep the same set of shortcuts and mental model. And i get to do some small automation on top of it with elisp, which I already do for the rest of my editor anyway.
adrian_b·12 ชั่วโมงที่ผ่านมา
Exactly as you say, the greatest difference with the recent generation of video terminal emulators that use the GPU through OpenGL or the like, is the much greater rendering speed, which becomes very noticeable with millions of lines of scrolling text, especially if you use high-resolution monitors.

Unfortunately, millions of lines of scrolling text are no longer unusual, especially when you frequently compile big software projects. The use of high-resolution monitors has also been normal for many years.

Instant window rendering is addictive, so now I would never return from a fast terminal emulator like ghostty to an older video terminal emulator. The last terminal emulator that I had been using before ghostty was kitty, which was also pretty fast in comparison with traditional terminal emulators, but I like ghostty more.
vijucat·10 ชั่วโมงที่ผ่านมา
Thank you, very interesting!
JoeBOFH·12 ชั่วโมงที่ผ่านมา
Honestly not sure. I used ghosty and others for awhile but had continuous issues of it not passing a compatible term variable so a lot of tuis would break.
adrian_b·12 ชั่วโมงที่ผ่านมา
This is normally a problem only when connecting to a remote computer through ssh, if you have not installed there the terminfo entry for ghossty or kitty or whatever recent video terminal emulator you are using.

If you do not want to or you cannot install the terminfo data, there is the easy workaround to put in your shell initialization script on the remote computer something like "export TERM=xterm-256color".

Ghostty aims to be completely compatible with xterm, so everything should work fine after setting thus TERM, only the newer features of ghostty will not be available.
homebrewer·8 ชั่วโมงที่ผ่านมา
https://ghostty.org/docs/features/ssh
dakra·7 ชั่วโมงที่ผ่านมา
Just want to add that we have the same feature in Ghostel.

As it copies stuff to a remote host, automatic ssh injection is disabled by default but you can enable it by setting `ghostel-tramp-shell-integration` to true.

For manual setup you can just copy a few lines from the manual in your shell: https://dakra.github.io/ghostel/#orgfea0bed
freedomben·16 ชั่วโมงที่ผ่านมา
zyralab·11 ชั่วโมงที่ผ่านมา