I have often executed `pkill -9 tmux` and saved my day. I hope the rust version can help a bit here?
Edit: As pointed out below, I'm stupid, it's stated in the article and I didn't read that part
1. Rewrite in (unsafe) Rust.
2. Update the code over time, moving towards safe Rust.
It's the old, "get it working then fix it" process. In business that's normally a bad idea because you end up wasting more time than if you'd just done things correctly from the start but for a hobby project it's fine. Because then you're more likely to learn something and possibly—ultimately—end up with a better end product.To a business, time your developers spend learning things (the hard way) is wasted.
To a hobbyist, taking the time to learn things is time well-spent.
The only reason this is at the top of HN is because of where Rust is on the Gartner Hype Cycle right now.
It's neat, but I wouldn't say useful.
https://www.youtube.com/watch?v=rWMQ-g2QDsI
Some of that video is about stuff you have no use for if you're not a Rust developer, but, some of it is things that would be just as useful to anybody who is comfortable with, as it says, a command line interface.
My dotfiles at https://github.com/nickjj/dotfiles have an install script to automatically get everything (including tmux w/ plugins) set up on Debian, Ubuntu, Arch Linux or macOS. This includes native Linux and WSL 2 support.
Looking forward to check out tmux-rs.
I entirely stopped using tmux when I couldn't use iTerm.
Have you checked out the website? This is a c2rust project. The Rust code is full of unsafe code and probably buggier than the C version, and let us not even mention readability and maintainability. Maybe there is a joke somewhere.
> I threw away all of the C2Rust output and decided I would translate all of the files into Rust manually from C.
The talk about starting with it, realizing it was too rough and changed approach. It's unsafe rust now but next goal at end was a safe version.
Have you read the conclusion, BTW?
It seems automatically translating Rust to C is not a very good idea: "I threw away all of the C2Rust output and decided I would translate all of the files into Rust manually from C.". Neither seems doing it manually: "I introduced many bugs while translating the code. I’d like to share the process of discovering and fixing a couple." Or using AI: "That’s because when using cursor to translate the code it would still occasionally insert bugs, just like me. So, I spent as much time reviewing the generated code as it would have taken me to write it myself."
As a hobby project, all power to you. But otherwise, maybe better not rewrite working code....
Except that the eventual result allows for extension and improvements in a memory-safe language.
Another comment in this thread hoped for "a brand new bulletproof tmux-resurrect". The reason there's a desire for such things is closely related to the limitations of non-trivial programs written in C.
They're harder to extend without bugs, harder for new team members to understand, and so on.
The "irrational obsession" has to do with advancing the state of the art beyond a primitive high-level assembler that was developed in the 1970s.
I find Rust fun and easy for writing system-level code, and I have enormous appreciation for the degree of correctness-by-construction that it can provide. Generally, if it builds, it works, as long as you're making proper use of the type system - make illegal states unrepresentable, as the saying goes. That's very difficult to do with C.
Rust isn't perfect. For most things, I'd rather be using Haskell, ML, or something on that level. But it's still on a completely different level from C, and rewriting the software ecosystem in it can only be an improvement.
Embed, designated initialization, and constexpr are really nice adds.
Statistically it is the most fun language there is, based on Stackoverflow. Portability is just a matter of time like with any language.
I maintain cargo-nextest, a widely-used test runner for Rust. It is possible to write nextest's runner loop in C, but it would be extraordinarily difficult — each test's state machine has dozens of states, there are several dynamic event sources as inputs, and the event loop relies heavily on epoll/kqueue/the equivalent Windows thing, as abstracted out by Tokio. So most test runners written in C don't even try to approach the quality, reliability, or portability of nextest.
It was born in the 1970s and was standardized in the 80s and 90s. It continues to develop. Numerous data types have been added, along with unicode and threads. The C23 standard was released last year.
There comes a point at which it becomes necessary to move on.
C's lack of memory safety covers a broad range of concerns, including manual memory management, unrestricted pointers, null pointers (Tony Hoare's "billion dollar mistake"), buffer overflows, use-after-free, integer promotions, and so on.
Its weak type system is another fundamental limitation, closely related to its limited support for abstraction. The weakness of the standard library reflects this. The weak type system means that the static guarantees it provides are minimal. There were excuses for all this in 1975, there aren't any more.
Undefined behavior is more of an issue in C than in most languages. Again, not something you ideally want in a systems language.
Language-level concurrency support is virtually nonexistent.
Use of textual preprocessing, with limited semantic integration, as a language feature. Aside from the effects on the meaning of source code, it also makes building C programs more complex.
And again, the reason C23 hasn't addressed any of this significantly is because of fundamental limitations in the nature of the language. You can't "fix" these things without developing a new language.
All of these languages are Turing complete. So ultimately, if you're happy writing code in some language and don't want to change, that's your choice. But the reason Fortran or C or C++ isn't many people's first choice for new projects are closely related to the reasons I've mentioned. There will always be people who want to stick to what they know, but it's not only science that advances one funeral at a time.
tmux has existed for approaching 18 years, and M. Marriott is still actively improving it as of last week. One can actually look at its record over that time, and, if that record is poor, replace proof by unsupported generalized assertion with proof based upon actual evidence.
* https://cvedetails.com/product/20683/Nicholas-Marriott-Tmux....
Also dev time is massively shorter and the time I gain is spent on adding more features and tests.
Would recommend building low level projects in something like zig, if you care about build time and don’t want to use a dependency for everything.
Sorry I know this is not the place to complain, but it would be so nice!
bind-key -n C-Space select-pane -t +1
Ctrl-Tab probably won't work because terminals tend not to recognize it as different from Tab. But you might be able to bind Alt-Tab or some other such combo to cycle through panes in the tmux config. It should just be a one-liner.
I've been working on a Rust-based tmux session manager called rmuxinator (i.e. tmuxinator clone) for a few years now. It (mostly) works and been slow going because ... life but I've recently picked it back up to fix some bugs. One of the last new features I'd added was the ability to use rmuxinator as a library in other Rust programs. I'd like to try forking tmux-rs, adding rmuxinator as a dependency and seeing if it would ... just work as a way to start sessions using per-project config files. I'm definitely not advocating for adding rmuxinator upstream but it would be very nice to have this sort of session templating baked into the "terminal multiplexer" itself.
The other interesting possibility I could foresee is doing things the other way around and having rmuxinator use tmux-rs as a library in order to setup and manage sessions instead of just dumping out shell commands -- which is fraught with edge cases. (Not sure if this is currently possible with tmux-rs, though.)
Once I wrap up the bugfixes I'm currently working on, I may fork this project and give one or both of the above a try.
Regardless, nice work by richardscollin!
Transitioning more software from C to Rust is a great idea.
If you're going to move a project to rust, you'd want to actually make it look like rust. Currently it looks like C written in rust. That doesn't make anyone happy really.
(Obv. not a slight on the maintainer here, it's a personal project with a specific approach)
I wonder, I don't expect.
This would require for the Rust implementation to grow beyond a POC with code translation before it entices any of the original authors or maintainers.
0. https://codemod.com/ 1. https://martinfowler.com/articles/codemods-api-refactoring.h...
That’s specific.
I was hoping for the announcement of a brand new bulletproof tmux-resurrect.
But no, it is (just) tmux-(recodedIn)rust.
Now I really wonder how a good model like Sonnet 4 would have performed.
What do you mean by this? I'd assume the process would be very very incremental. One function + accompany tests at a time, verify and continue and keep moving up the tree.
It's an interesting problem because I imagine in the future lots of things will be ported like this.
-edit Good luck reading 100k lines of Claude generated Rust that you know nothing about lol. LLMS are not the tool for this.
> I did start trying out Cursor towards the end of the development process. I ended up stopping using it though because I felt like it didn’t actually increase my speed. It only saved me from finger pain. That’s because when using cursor to translate the code it would still occasionally insert bugs, just like me. So, I spent as much time reviewing the generated code as it would have taken me to write it myself. The only thing it saved was my hands. Doing this large amount of refactoring is really hard on your fingers.
Here I want to call out zellij. Zellij is rust based terminal multiplexer.
I am user not creator. I love everything rust and finding and migrating to rust based solutions where feasible.
In fact, I sometimes port code to another language and back just as a way to do code cleanup (or at least give ideas for things that could be cleaned up)
I wonder why OP didn't start from that as a starting point?
Sounds to me that this was a C -> Rust transpiler. :D
Edit: I was right, they used c2rust.
And then there is "// generated Rust code".
As for the code snippets on https://richardscollin.github.io/tmux-rs/, I can read the C version better than the generated Rust code.
// cmd-kill-session.c
RB_FOREACH(wl, winlinks, &s->windows) {
wl->window->flags &= ~WINDOW_ALERTFLAGS;
wl->flags &= ~WINLINK_ALERTFLAGS;
}
// cmd_kill_session.rs
for wl in rb_foreach(&raw mut (*s).windows).map(NonNull::as_ptr) {
(*(*wl).window).flags &= !WINDOW_ALERTFLAGS;
(*wl).flags &= !WINLINK_ALERTFLAGS;
}
Please let me know which one is more readable to you.It is auto-generated with the purpose of maintaining the exact same semantics as the C code, with no regard to safety, best practices, etc.—of course it is messier than actual, handwritten Rust.
As c2rust says in its documentation [1], it's meant to be the first step in an otherwise manual and incremental port of a codebase from C to Rust, and the author recognizes this in their closing remarks:
> The next goal is to convert the codebase to safe Rust.
[1] https://github.com/immunant/c2rust/raw/master/docs/c2rust-ov...
Have you read the conclusion, by the way?
It is probably going to end up being vaporware.
Given the traction you got here and the advancements in AI, I'm sure this can become a very attractive hobby project for Rust beginners, there's probably a lot of easy bugs to fix. Fixing bugs, adding new features, and optimizing the code is all you need.
Here's an idea to get the ball rolling: Create a scratch buffer for Gemini CLI (or your favorite LLM) and enable it to interact with the various windows and panes of the tmux session.
Here's my use case, I use synchronized panes to send the commands into multiple servers, but some commands sometimes fail for various reasons. What if I can just ask the AI to send a series of commands and react based on the output and adjust along the way. It's like a dynamically generated custom shell script on the fly.
120 comments and nobody has mentioned the use-after-free triggered by closing a window. Rust truly is the safest language.
Which makes C2Rust seem pretty useless?
"I’ve recently reached a big milestone: the code base is now 100% (unsafe) Rust. I’d like to share the process of porting the original codebase from ~67,000 lines of C code to ~81,000 lines of Rust (excluding comments and empty lines)."
And yet somehow a hand-ported (and still unsafe) rewrite of a C program in Rust is still almost 20% larger?
If I recall, the Go gc compiler was automatically converted from 80K lines of C to 80K lines of Go. A hand-ported version would have been much smaller.
Love it. You definitively deserve your +350 points!
And as a result, you could be running the greatest / fastest / most feature rich desktop terminal … but if your multiplier doesn’t support something - it hinders your fancy desktop terminal.
Short 3 min video explained by Ghostty creator
you want to re-implement a well known project, fine
call it something else
mbreese•5h ago
I love this attitude. We don’t necessarily need a reason to build new things. Who knows what will come out of a hobby project. Thanks to the author for the great write up!
Also, my gardening is full of segfaults, coding a new project is definitely safer to my yard.
upmind•4h ago
ziml77•3h ago
phkahler•2h ago
nisegami•4h ago
Edit: apparently it did turn out to be a lot of unsafe code
miroljub•4h ago
Every new project is bound to have bugs that need to be ironed out during the time.
Ar-Curunir•4h ago
a_humean•4h ago
nicoburns•58m ago
antonvs•3h ago
You'd have to do a proper rewrite, in which case you could write safe code from the start.
> Every new project is bound to have bugs that need to be ironed out during the time.
Not on the level of the kind of critical security and reliability bugs that unsafe languages foster. That's why CISA and the FBI both strongly recommend memory-safe languages.
QuaternionsBhop•3h ago
nicce•3h ago
Jtsummers•4h ago
ar_lan•2h ago
> the code base is now 100% (unsafe) Rust
I didn't interpret that it's 100% unsafe, but I do expect that to mean there is probably a lot of unsafe blocks used. A good amount of the example code in the post alone is unsafe blocks as well.
cultofmetatron•3h ago
interesting, I'm new to rust. what are you doing that necessitates using unsafe?
tshaddox•3h ago
jeroenhd•3h ago
C pointers can have as many owners as you want, may be subjected to mathematical operations, and can be cast to any type without even an error message. The compiler will just assume you know what you're doing. If you enable enough compiler warnings, it might warn you, but C compilers don't generate a lot of those by default.
Rust will let you only generate one mutable (exclusive) reference at a time. This means straight C to Rust ports simply don't compile.
By switching to pointers, which work pretty much like their C equivalent, you can port the code much easier, but you do of course lose the benefits of Rust's safety mechanisms, because most pointer operations throw away all the safety guarantee that Rust provides.
SoftTalker•2h ago
cuu508•2h ago
petrzjunior•2h ago
planet36•3h ago
tombert•3h ago
I recently rewrote `fzf` [1] in Rust. Did I have any particular reason to do so? No, not really, regular `fzf` is fine, but I thought it would be a fun excuse to learn how fuzzy search algorithms work and how to exploit the channels in Rust. It was fun. There's no question that regular fzf is better but that wasn't the point, the point was to play with stuff and learn.
[1] https://github.com/Tombert/rs-fzf-clone
carlmr•12m ago
[1] jhawthorn/fzy: :mag: A simple, fast fuzzy finder for the terminal https://share.google/TBp3pVaFngBTfaFyO
rauli_•2h ago
dsp_person•1h ago
johnisgood•34m ago
godelski•1h ago
And frankly, to quote Knuth
This is true for any field, or any project. We're creative creatures. We dream and explore. Major changes almost never come from doing things the way they've always been done. A lot of times "just because" gives you the freedom to try new things and challenge those paradigms. Weirdly, if you always have to justify everything you slow down progress.Arisaka1•39m ago
badgersnake•42m ago
Or copies of old things apparently.