Introducing tmux-rs
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....
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.
developed in the 1970s.
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.
There are certainly a lot of dangerous aspects, but most are rather easily avoided.
This is an almost childish claim. If they're so easily avoided, how do you explain the enormously long list of CVEs for C and C++ programs?
I do not think C++, Zig, or Go have a fundamental advantage.
We agree on that. They objectively do not. They're all an attempt to continue the C legacy. Go specifically is particularly ridiculous, having been designed quite recently by people from the 1970s who steadfastly refused to learn any lessons from the last 50 years of programming language development.
To be clear: I'm from the 1970s as well. I learned FORTRAN in 1977. But unlike the designers of Go, I didn't allow my understanding of programming language design to stagnate in the 1970s. I learned things. I studied things. I discovered things.
Do you believe that C is the ultimate in system programming language design? If you agree that it's not, then what are we arguing about exactly?
While I'd hardly disagree C and even C++ is lacking in memory safety compared to some newer languages, you are forgetting to normalize for sheer scale and userbase. If you have a Go project with the scale of popularity of Linux or Chrome or so on, then we can compare bug counts directly.
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.
There are more factors to language use than design pattern fads. Like efficiency for example, which almost any modern garbage collected or managed language cannot meet beyond a certain level. And that usually gets worse the more "powerful abstractions" one adds. I want to learn FORTRAN because I have been told it has real benefits in terms of ergonomics for efficient code, ie normal looking FORTRAN code is faster than normal looking C/C++/Rust.
Efficiency is a real, concrete and measurable quantity. It is not subject to the fad of the day.
You end up with long-term fads like class-based object orientation embedded in the language, and that inhibits them evolving towards more principled designs.
And what makes you think today's "principled designs" won't get the boot a few years down the line too? These things are cyclical and rarely based on any real mathematical reasoning.
It's a different way of thinking about languages than most people usually do, but it's been true for FORTRAN since the 1950s and is true to some extent of every language with multiple implementations today.
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 is possible to do this in C, because it compiles to machine code in the end. But would be out of reach for all but the most talented of C teams working over many years, and the portability costs would be massive. As a result, I don't know of a test runner that comes anywhere close to the feature set and portability of nextest that's written in C.
I think you have no idea how big the C ecosystem is.
I'm definitely aware that the C ecosystem is much larger than the Rust ecosystem.
I also doesn't seem like anything most people would spend a lot of time on.
That's because the conditions created by C make solving this problem very hard, not because the problem isn't worth solving.
It is still a hard problem with Rust, requiring heavy use of async state machines to manage a rather extraordinary level of complexity. But at least it is possible for essentially a solo dev like myself to do in a robust, largely bug-free manner.
I run my tests using "make" which somewhat poor but does the job.
Right, "make" is indeed not quite a high-performance enterprise-grade test runner with parallel test execution, high-quality reporting, signal handling, dynamic status querying, timeouts, retries, flaky test detection, mutual exclusion between tests, a DSL that lets you specify sets of tests, flexible configuration, archiving tests to run on another computer, sharding test runs, JUnit support, wrapper scripts, setup scripts, and several other features. Make doesn't even properly support Windows, which is table stakes for a portable test runner.
You're welcome to peruse the design documents:
https://nexte.st/docs/design/architecture/runner-loop/ (already linked above)
Rust is not portable at all compared with C code.
C definitely has a place, but "Rust is not portable at all compared with C code" is simply not correct. A lot more Rust code works across Windows and Unix than C code does. Rust's portability story is different from C's, much better in many ways but worse in others. In practice I do think Rust ends up being more portable than C in most practical scenarios -- for example, look at how things like `eza` work on Windows, the number one developer platform worldwide.
It is also less fun
Statistically it is the most fun language there is, based on Stackoverflow. Portability is just a matter of time like with any language.
It's not that we are simply waiting for the backport of Rust to magically appear for them, it's quite a certainty that it will basically never appear.
Abstraction happens on the level where tmux requirement is irrelevant. When the usage of Rust gets wider, people start adding support on compiler level for other needs. It is inevitable.
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.
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.
I don't follow; tmux-resurrect isn't written in C and is mostly useful to keep sessions across reboots.
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....
That is still quite a good record, but my statement stands. It is supported by decades of my experience working in C-derived languages. You don't have to accept my experience or believe my statement, of course, it's all the same to me.
...and before someone moans that I'm a C-fanboy, I'm really not. I've been writing software exclusively in memory-safe languages for 10+ years now. But I'm also pragmatic about when arguments about a RiR (rewrite-in-rust) are sensible and when they're not. In tmux's specific case, arguing about security misses the point.
If you care about security enough to be concerned about memory-safety bugs in tmux, then tmux is already a fail, regardless of whether it's written in Rust. I detailed some features in another comment about some of tmux's features that basically make it spyware for untrusted code. And that's got nothing to do with the language it is written in.
But assuming you only care about terminal output and trust the software you execute, then you still have a hundred other libraries written in C between and tmux and the internet: openssh, libcurl, openssl, glibc, and so on and so forth. I'd actually welcome seeing many other those rewritten in Rust (or another memory safe language). So rewriting tmux before them is a lot like closing the barn door after the horse has already bolted.
Thus if you're genuinely concerned about memory safety security vulnerabilities then the only safe way to work with untrusted output is in a VM.
As it happens, this is exactly how highly secure systems operate. Their developers work on VMs which are tightly locked down by the vendor and easy to destroy if they become compromised.
Literally the only way to solve the problem you describe is to assume the entire stack is already compromised and thus run it in a sandbox.
So does rewriting tmux in Rust improve security? Yes, technically you're right. But it makes almost zero practical benefit compared to everything else. Memory-safety in tmux is not your weak link here. Not even remotely.
Disclaimer: I've developed terminal emulators, shells and terminal multiplexers in memory safe languages. My latest project makes heavy use of tmux integrations (again, in a memory safe language) so I'm very familiar with tmux's quirks. I also have a background in DevSecOps. You could almost say this topic is my specialist subject ;) The Rust hype is a generally good thing but misplaced in this very specific discussion.
I know you say you’re not viewing things in black and white, but “run in a VM or don’t care about security and vulnerabilities don’t matter” is exactly that.
I’ve already said there are other applications I do think benefit from a memory safe rewrite.
I don’t need to access untrusted sources from tmux. I do from Firefox.
Tmux has a smaller, easier to audit code base. Browsers are large, complicated and sprawling projects. That makes browsers a much larger attack surface.
Browsers already have sandboxing and other mitigations. Tmux doesn’t. Which means there are lower hanging fruit to fix in the terminal vs web browser.
Browsers are used by more people than tmux. So it’s a juicer target for zero-days.
We also already have Rust-based multiplexers for people who are worried about memory safety. There isn’t for web browsing.
Security is a scale of risk rather than something that is black and white. At some point the scales will tip and rewriting tmux in rust makes sense. But as said earlier, we already have Rust-based multiplexers for that eventuality. Whereas the need to harden browsers is much more urgent.
Context matters when it comes to InfoSec. At this point in time, rewriting tmux in Rust offers marginal gains vs rewriting a browser in Rust.
Maybe you never expose your terminal to untrusted data, but that’s not the norm. Most people occasionally do things in their terminals like clone repositories and look at their READMEs, ssh to computers they don’t own, read email, even browse the web.
Note that I’m not arguing that tmux must be rewritten in rust for security. I’m saying that C code is virtually guaranteed to have vulnerabilities, and this is a major reason why people want to rewrite things in rust.
If you want to argue that tmux doesn’t have any vulnerabilities, I find that very unlikely, but you do you.
If you want to argue that rewriting tmux in rust isn’t worth the effort, you may be right, but you’re arguing against something I didn’t say.
My replies have been specifically about that those merits.
The only reason other arguments have been included is because people like to expand that scope. For example where you said (and I’m paraphrasing) that tmux isn’t free from bugs. Clearly I don’t believe that any software is 100% bug free. But that doesn’t mean that rewriting tmux in rust brings any pragmatic improvements to the table when weighed up against all the other options and concerns.
I summarized my actual statements in the previous comment. You might infer (and quite reasonably so) a claim that a rust rewrite would be more secure. But any statement about the overall usefulness of such an endeavor is solely in your imagination.
You never run curl dumping to stdout?
Not against untrusted URLs, no.
You never cat or less a file you downloaded?
I don’t download untrusted files.
You never ssh to servers run by other people?
100% no.
——-
Sounds like what you need more is a VM ;) executing anything untrusted in a secure environment is a dumb move.
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.
1. anything running in tmux already has execution rights and typically for the same user as tmux anyway.
2. Anyone who wanted to exploit tmux could just run ‘tmux -C’ and automatically get access to literally every interaction within tmux.
3. The software itself is already damn stable. I've never had it crash.
If you’re worried about someone exploiting your terminal then tmux is a terrible option, irrespective of whether it’s with written in C or Rust. And I say this as someone who absolutely loves tmux and uses it every day.
[edit]
And if you're worried about non-security related bugs affecting UX, then a rewrite in any language, regardless of the language, is a worse solution if your application has already been battle-tested for close to two decades. You're much better off creating something entirely new instead of porting code from one language to another because at least then you have new ideas instead of the same application but with new bugs in different places.
I don't say this because of some bias that Rust fanboys will assume I have. I love memory safe languages and think Rust is a great option for new projects. The point I'm making here is that a rewrite doesn't gain much for tmux SPECIFICALLY because tmux is already extremely stable.
I honestly don't get this relentless defense of 1970s-style programming. Do you think C is the pinnacle of programming language design? No? Then what's your point, exactly?
Any program gains from memory safety. Memory safety is not just about security. It's about eliminating an entire class of bugs - buffer overflows, null pointer errors, use-after-free, the list goes on. They just so happen to be the kind of bugs that also tend to have serious security consequences.
Have you actually ever encountered such a bug in tmux though? Because I've been using it for around 15 years and can honestly say I haven't.
Yet this rewrite has introduced bugs. I know it's a hobby project so I'm not being critical. But if you're just trying to reduce bugs then rewriting code battle tested code in another language, regardless of that language, isn't the right way to go.
I honestly don't get this relentless defense of 1970s-style programming. Do you think C is the pinnacle of programming language design? No? Then what's your point, exactly?
Where was I defending 1970s style programming? I wasn't even defending C. In fact the last project I've worked on based in either C or C++ was 10 years ago. Believe me, I'm a fan of memory safe languages ;)
My point was very clear and very specific to tmux. You're just trying to read between the lines and create a whole new argument where there was none.
Have you actually ever encountered such a bug in tmux though? Because I've been using it for around 15 years and can honestly say I haven't.
Since you asked, once every few months or so the whole server crashes which takes out all my windows. I don't know what exactly triggers it, other than it being something to do with pasting, and it's so infrequent that I haven't bothered to investigate it. Obviously the trivial repro of just pasting the same thing I tried to paste the first time doesn't repro it; I'd need to gdb the coredump, which is :effort:
I wouldn't expect this Rust rewrite or any other rewrite to fix it in any case; it would be more efficient to figure out the crash and fix it in the original C version.
You forget that tmux is a terminal emulator.
No I don’t forget that.
can output malformed unicode or escape commands that trigger crashes or code execution, it is actually a huge problem.
I agree.
And to go back to an earlier point, when was the last time you experienced tmux crash? Because I’ve been using it 15 years and yet to see that happen to me.
I get the need to protect against theoretical attacks, but what you’re advocating is throwing the baby out with the bathwater.
CVE-2020-27347 is exactly the kind of memory safety bug exploitable by terminal output that I was talking about.
As I said elsewhere, if memory safety is a major concern then there are Rust multiplexers too. But there’s plenty more lower hanging fruit to worry about before tmux.
In fact the author of this project has admitted that they've introduced bugs with their rewrite. I know it's a hobby project so I'm not being critical of their work. But if we're only interested in reducing bugs then rewriting an existing project isn't the right way to go. Something like Zellij makes more sense because it's offering something new in addition to being written in Rust.
https://github.com/dotnet/runtime/pull/115762
https://github.com/dotnet/runtime/pull/115743
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.
And frankly, to quote Knuth
> In fact what I would like to see is thousands of computer scientists let loose to do whatever they want. That's what really advances the field.
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.To me it sounds like you learned a real important lesson one that some people never seem to learn.
I think one of the most beneficial aspects of doing things "just because" is these other skills or information you get along the way. It is very easy to miss all of this progress if you're too focused on the progress of the more tangible things. But that doesn't make any of that not progress. So don't put yourself down for that, because I'm sure you learned a lot. The only reason you can look back and see a better way is because you made that progress and learned those lessons. These are things mentors can usually help you get through faster but not everyone has a mentor nor access to one. But don't undermine your own progress just because you didn't finish projects or because you did things differently than others
other people use the stupidest possible javascript to launch product and really focus on product and marketing
yet other people stay as far away from computers as possible and focus on more human activities
you just do what you're drawn to naturally
I treat projects differently if they want to launch a product, they want to replace an established open source tool, done for fun for themselves, or if it’s a hobby project.
Follow up questions are totally cool but the context is different, right?
If it isn't acceptable then there's a negative tone and questions are focused on utility and usually them "trying to help you" find utility.
If it is acceptable they ask you about your interests and what you're learning. Sometimes that can turn into utility but that's more natural.
It's a lot about culture to be honest. Some people are just toxic and if things don't make sense in their heads then it doesn't make sense in any head.
Like gardening, but with more segfaults.
interesting, I'm new to rust. what are you doing that necessitates using unsafe?
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.
In C you only see the flags people know of or remembered to plant. There's an awful lot of mines left unflagged and sometimes you step on them.
It's very obvious to me which would be more safe and I find myself questioning why it is isn't so obvious to others.
Hmm...I like when the assembler don't steps in my way and assumes that I know what I'm doing. Thats the reason why I don't like C, and prefer assembler. But when you like it, have fun!
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] jhawthorn/fzy: :mag: A simple, fast fuzzy finder for the terminal https://share.google/TBp3pVaFngBTfaFyO
Someone smarter than me who is more familiar with TUI programming could almost certainly augment and improve what I wrote; I worked on it for as long as it was interesting to me. I use it for my home-built program launcher thing Sway, though most people would probably get better results with real fzf.
[1] https://github.com/Tombert/rs-fzf-clone/blob/main/src/helper... [2] https://github.com/Tombert/rs-fzf-clone/blob/main/src/proces...
And assuming speed is not an issue, why would Rust make it better?
For command line tools I just appreciate if they're as fast as possible. And rg, fd, etc just show that Rust implementations can be correct and fast.
We don't necessarily need a reason to build new things.
But tmux isn't new
Is a reason necessarily needed to rewrite software in other languages
The latter reason is why Helix is slow in doing similar to vim, I think, despite being far more consistently designed and saner defaults. Everyone knows vim exists.
I've still never switched from screen, personally, though I'm only a light user.
status bar out of the box
Software packages win over other packages for the silliest reasons.
GNU screen would like a word.
Screen, tmux, byobu, dvtm, mtm, Twin, and most of all Zellij, which is basically "tmux but redone in Rust".
I tried to compare them all a month ago:
https://www.theregister.com/2025/06/24/tiling_multiplexers_s...
Edit: apparently it did turn out to be a lot of unsafe code
Every new project is bound to have bugs that need to be ironed out during the time.
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.
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.
The experience with `c2rust` is particularly interesting. It reminds me of a similar shift I saw years ago with automatic code translators between other languages. They're incredible for getting a project off the ground and proving feasibility, just as the author found, but you often end up with code that's completely "un-idiomatic" for the target language. The decision to throw it all away and do a manual port, while surely gut-wrenching, was the right call. You just can't automatically translate the intent of the original C code into safe, idiomatic Rust.
The "Interesting Bugs" section gave me flashbacks. Bug #2, with the mismatched struct layout due to a missing `*`, is a classic FFI (Foreign Function Interface) nightmare. I once spent the better part of a week debugging a similar issue between C++ and C# where a single change in struct packing alignment was silently corrupting data downstream in very subtle ways. It's one of those bugs that makes you question your sanity. Finding that requires some serious debugging grit, so kudos to the author.
This project is a great case study in the real-world challenges of modernizing critical infrastructure code. The author mentions the next big goal is to convert the codebase from `unsafe` to safe Rust. I'm really curious about the strategy for that.
Refactoring away the raw pointers and complex control flow (like the `goto` patterns) into safe, idiomatic Rust without breaking everything seems like it would be even more challenging than the initial port. Will the approach be to introduce lifetimes and the borrow checker module-by-module? And what's the plan for the intrusive data structures? Replacing them with standard library collections like `BTreeMap` is the obvious choice, but I wonder if that will have performance implications that the original intrusive design was meant to avoid.
In any case, amazing work. Thanks for sharing the journey in such detail. I'll be following this project on GitHub for sure.
Transitioning more software from C to Rust is a great idea.
rust isn't a good fit for them (for reasons that summarize to portability problems)
These problems are largely solved now that there's a working transpiler from Rust to C - https://github.com/FractalFir/rustc_codegen_clr
This project is still early in its developement. Bugs, crashes and miscompilations are expected. DO NOT USE IT FOR ANYTHING SERIOUS.rustc_codegen_clr is only tested on Linux x86_64, with the CoreCLR runtime (more commonly known as simply the .NET runtime), on .NET 8. It should work on other platforms, but it is not guaranteed.
I guess it could eventually be an option, but today it looks more like a neat tech demo.
to expect
I wonder, I don't expect.
This would require first for the Rust implementation to grow beyond a POC with code translation. In its current state I doubt it could entice any of the original authors or maintainers. But if it became capable and hardened and picked up velocity, then it would pose some major questions for having two similar pieces of software.
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)
Now I really wonder how a good model like Sonnet 4 would have performed.
It wouldnt have gotten 2% finishd
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.
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.
Interesting, this article and the comments make no mention of LLMs.
the code base is now 100% (unsafe) Rust
So the primary (or rather: only) reason for using Rust over C (memory safety) is out the window.
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
And the codebase got bigger.
So yeah, as the author explains, hobby project, and kudos to that, but nothing that I will install on any box of mine any time soon.
Besides, applications like tmux would much rather be prime candidates for a rewrite in a garbage collected systems language (aka.; Go) than in Rust. tmux spends 99% of its time waiting for the user to hit a key, there is nothing performance critical in such an app that wouldn't be 100% adequately served by Go.
Did you even the article? He clearly states his aims to convert it to safe rust. And for the code size, he clearly hasn't needed to optimize it yet and I don't think you necessarily want to code golf codebase like this.
but nothing that I will install on any box of mine any time soon
Well, no one asked? I will never understand you chronically negative people that have to come in and whine about things that don't matter every time someone posts their fun little personal project that they made for fun. Have you tried being a little more positive? It makes life more enjoyable.
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.
I suspect it’s a couple of things. A new generation of programmers are hitting the scene, wanting to do things in new ways. Not inherently good or bad, but the new tools sure usually are at least very _pretty_, and have a lot of affordances and usability improvements over the ancient tools that can never be changed for the sake of compatibility. Rust and Go make this nicer, and are the languages de jour with good cli ecosystems and performance characteristics around them.
I genuinely do like most of my replacements. ripgrep for grep, eza for ls, zoxide for cd, fd for find, podman for docker, and a few more. Developer tooling is a rich and interesting space to be in, but there’s plenty of bandwagons I’m not getting on, like this or zellij for tmux, or jj for git.
zoxide for cd
i'm sorry WHAT
Basically, when tou type "cd some/subdir", these tools remember the frequency/recency of durectories you cd into, so at some point you can type "z sub" and they teleport you to "some/subdir" no matter what's your current working dir.
I love it and use it daily. Zoxide just has some nicer features than the alternatives (and maybe it's faster).
Looking forward to check out tmux-rs.
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.
Sorry I know this is not the place to complain, but it would be so nice!
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.
bind-key -n C-Space select-pane -t +1
Works great and it's totally memory safe
It's probably foolish, but I have the idée fixe that there's really no solid alternative for graphviz and dot (yes, there are UI versions, and mermaid and whatnot, but nothing that works on really big graphs and has the same expressivity), and I suspect that soon all the people that wrote graphviz will die off or retire. I like to see a port to a newer language as well, so ongoing maintenance will bercome easier.
Again, probably an idée fixe, and all is really well.
Try to port it. Maybe it'll just work
I have often executed `pkill -9 tmux` and saved my day. I hope the rust version can help a bit here?
Also, in 2017-2018 I contributed a few fixes for memory leaks related to buffer history, so make sure you are using a recent version.
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.
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.
Which makes C2Rust seem pretty useless?
It does what took him 6 months in seconds. Of course it isn't perfect, failing to keep the name of constants being an obvious flaw. But presumably with a few improvements you could then spend some of that 6 months cleaning up the code and still save time. Sounds like C2Rust is almost there, but not quite yet.
And yet somehow a hand-ported (and still unsafe) rewrite of a C program in Rust is still almost 20% larger?
Size is not a very useful metric. But the port is still half-done. He has got it working in Rust, so now he is ready to do the "hard" part of the port and actually rewrite the "basically C" code into idiomatic Rust. That is where you expect to get safety improvements and hopefully more readable code.
It generated unusuable garbage code in seconds, which is nothing like what he wrote by hand in six months.
"Size is not a very useful metric."
Size is a very useful metric. Counting tokens is more accurate estimate of "size" but lines of code is a good first approximation.
The entire purpose of high level languages is to make it possible to do more with less code. Size isn't all that matters but it's very important.
Rust code is not only more verbose than C it's also much more irregular and complex. That 20% increase in lines of code is probably more like 50% increase in code complexity, and this is without safety.
Just compare tokens in the post's example:
// 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;
}
This seems like an excellent future use case for a fully automated process by a large language model that translates a non-trivial C codebase to Safe Rust in under an hour with high accuracy.
That’s specific.
0. https://codemod.com/ 1. https://martinfowler.com/articles/codemods-api-refactoring.h...
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.
For example, I'm a daily gvim user. If I were going to do a hobby project text editor, I would emphatically not make a clone of gvim, I'd make a text editor with exactly the features I want that behaves exactly how I want. If you're going to invest that much time in a project, why not do something creative and unique?
you want to re-implement a well known project, fine
call it something else
Luckily tmux has a well-established "control mode" protocol designed for iTerm2 that can serialize internal state updates into a stream of text messages. So I do write client-side of this feature right inside tmux.
When it's ready, you will able to embed remote sessions inside local tmux instance by calling something like "ssh example.com tmux -CC attach". It will auto-detect "control mode" escape sequence and create special "remote session" you can switch into.
If you are interested, connect with me (snizovtsev@gmail.com) so I will notify when feature is ready and ask for early testing before making upstream proposal.
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!
I walked through the code again. Inside of the Rust function (*c).bar has a valid address, like 0x60302764, but out the function, the value received from the calling C code was 0x2764.
...
That’s right, the C code was using the implicit declaration which is:
int get_addr();
That explains why the value was incorrect! The C compiler was thinking a 4 byte int was returned not an 8 byte pointer. So the top 4 bytes were being truncated or ignored.
That's weird as an explanation. 0x60302764 is 4 bytes and 0x2764 is 2 bytes. Why would an address get truncated to 2 bytes? Is int 2-bytes according to any intermediate compilation stage? (Been at least 25 years since I saw int be 2 bytes, if ever).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
120 comments and nobody has mentioned the use-after-free triggered by closing a window. Rust truly is the safest language.
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 feeling is that I’d still reach for it if my hands are really physically hurting, and I need to keep working. Usually once I reach the point where I’ve got blisters on my fingers I think it’s better to just take a break
I'm dumbfounded, and impressed in an unhealthy way. Do some of you regularly type so much that you develop blisters?
Then again, by the time I had a touch typing course at age ten using an old typewriter, I already had taken piano lessons for a couple of years. My music teacher was very strict on proper hand positioning, saying that future me would hate him if I didn't learn that right. I stopped taking piano lessons soon after, but I imagine that the skills involved with properly playing the piano transfer quite well to typing.
I learned piano earlier in my life and then learned touch typing (and shameless plug: built https://www.typequicker.com) later on in life and I definitely had a easier time than some of my peers.
I’m curious - what course did you take (might have been a while) ? I’m hoping to built features in TypeQuicker for institutional clients (schools, tutoring agencies, etc) and I’m doing research on what some schools currently use.
Many don’t have any courses at all so it’s a hard sell right now
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?