Hacker Newsnew | past | comments | ask | show | jobs | submit | more qudat's commentslogin

Are you using it only on massive codebases? It's much better with smaller codebases where it can put most of the code in context.

Another good use case is to use it for knowledge searching within a codebase. I find that to be incredibly useful without much context "engineering"


It's also good on massive codebases that include a lot of "good practices" examples.

Let's say you want to add a new functionality, for example plug to the shared user service, that already exist in another service in the same monorepo, the AI will be really good at identifying an example and applying it to your service.


Insert before 4: make it generate tests that fail, review, then have it implement and make sure the tests pass.

Insert before that: have it creates tasks with beads and force it to let you review before marking a task complete


I think generics ruined the language. Zig doesn’t have them


But it has something for it (compile time evaluation of functions).


I want to add a `zmx switch` command to detach+reattach to another session. Still thinking through the impl.


Great point! I'll add a comparison to the readme.

To answer your question directly: abduco does not restore terminal state or history. All it does is force a redraw on re-attach. This works for some programs but for many it does not (e.g. htop).

zmx holds onto terminal state and history and sends a snapshot on re-attach.


I run a similar site (https://pico.sh) with public urls and thought the same thing for us. The public suffix has some fuzzy limits on usage size before they will add domains (e.g. on the scale of thousands of active users).

I don’t have tunnl.gg usage numbers but I’m going to guess they are no where near the threshold — we were also rejected.


I just want to say that I love pico.sh <3


much appreciated!


I'm excited to see where this goes. I recently did some io_uring work in zig and it was a pain to get right.

Although, it does seem like dependency injection is becoming a popular trend in zig, first with Allocator and now with Io. I wonder if a dependency injection framework within the std could reduce the amount of boilerplate all of our functions will now require. Every struct or bare fn now needs (2) fields/parameters by default.


> Every struct or bare fn now needs (2) fields/parameters by default.

Storing interfaces a field in structs is becoming a bit of an an anti-pattern in Zig. There are still use cases for it, but you should think twice about it being your go-to strategy. There's been a recent shift in the standard library toward "unmanaged" containers, which don't store a copy of the Allocator interface, and instead Allocators are passed to any member function that allocates.

Previously, one would write:

    var list: std.ArrayList(u32) = .init(allocator);
    defer list.deinit();
    for (0..count) |i| {
        try list.append(i);
    }
Now, it's:

    var list: std.ArrayList(u32) = .empty;
    defer list.deinit(allocator);
    for (0..count) |i| {
        try list.append(allocator, i);
    }
Or better yet:

    var list: std.ArrayList(u32) = .empty;
    defer list.deinit(allocator);
    try list.ensureUnusedCapacity(allocator, count); // Allocate up front
    for (0..count) |i| {
        list.appendAssumeCapacity(i); // No try or allocator necessary here
    }


I’m not sure I see how each example improves on the previous (though granted, I don’t really know Zig).

What happens if you call append() with two different allocators? Or if you deinit() with a different allocator than the one that actually handled the memory?


Storing an Allocator alongside the container is an additional 16-bytes. This isn't much, but starts adding up when you start storing other objects that keep allocators inside of those containers. This can improve cache locality.

It also helps devirtualization, as the most common case is threading a single allocator through your application (with the occasion Arena allocator wrapping it for grouped allocations). When the Allocator interface is stored in the container, it's harder for the optimizer to prove it hasn't changed.

> What happens if you call append() with two different allocators? Or if you deinit() with a different allocator than the one that actually handled the memory?

It's undefined behaviour, but I've never seen it be an issue in practice. Expanding on what I mentioned above, it's typical for only a single allocator to be used for long live objects throughout the entire program. Arena allocators are used for grouped allocations, and tend to have a well defined scope, so it's obvious where deallocation occurs. FixedBufferAllocator also tends to be used in the same limited scope.


I think a good compromise between a DI framework and having to pass everything individually would be some kind of Context object. It could be created to hold an Allocator, IO implementation, and maybe a Diagnostics struct since Zig doesn't like attaching additional information to errors. Then the whole Context struct or parts of it could be passed around as needed.


Yes, and it's good that way.

Please, anything but a dependency injection framework. All parameters and dependencies should be explicit.


I think and hope that they don’t do that. As far as I remember their mantra was „no magic, you can see everything which is happening“. They wanted to be a simple and obvious language.


That's fair, but the same argument can be made for Go's verbose error handling. In that case we could argue that `try` is magical, although I don't think anyone would want to take that away.


libghostty is stellar! I’m using it for my session persistence for terminal processes tool: https://github.com/neurosnap/zmx

When users reattach to their session we render the terminal state and output from ghostty. Super cool and works really well. It’s basically tmux-lite in 1k LoC


I like that. I don’t want to use tmux (and I don’t when I’m working on my local machine), but I can’t escape it when SSHing. I could ssh to a ton of sessions, but then I 1. Have to remember their names 2. Can’t easily create a new pane (on the remote host) for some short task and 3. Need yet another solution for restoring my pane layout for when my client restarts.

Maybe I’ll try the session name thing, I just foresee it being annoying. Do you see your tool as a shpool replacement?


Yes this completely replaces `shpool`.

I totally understand your concerns for creating new terminals for short tasks. I generally lean towards `nvim` terminal buffers to solve that issue. Or I have a `term` session open that I can quickly go to for random terminal commands that don't belong to a project.


Don't give them useful names, just call them 1 or 2 or asdf and let your brain do the mapping.


I also (coincidentally) just started using OP's coder, and that also sets up ssh config to use special wildcard hosts, and unfortunately 'hogs' the config (it threatens to trash any changes to the coder section).


Love this idea. Though, apparently zig isnt available in any version of Debian including sid, which is annoying. A multiyear packaging effort stalled out 8 months ago with zig 0.14, which is too old for zmx.

Will try this out on my arch system later this week though.


My next step is to package this tool so people can easily install it.


This is super cool! I didn’t know I was looking for exactly this, but I am


Text search has been merged on main


I’m curious, how do you know it was inspired by tiger beetles impl?

They look very similar so that makes sense, just curious on the order of events.

Also I tried using libxev for a project of mine and found it really broke the zig way of doing things. All these callbacks needed to return disarm/rearm instead of error unions so I had to catch every single error instead of being able to use try.

I could have reworked it further to make try work but found the entire thing very verbose and difficult to use with 6 params for all the callback functions.

Thankfully my use case was such that poll() was more than sufficient and that is part of zigs posix namespace so that was what I went with.


> I’m curious, how do you know it was inspired by tiger beetles impl?

Describing its design, the readme for libxev says "credit to this awesome blog post" and links to the same Tigerbeetle post in this submission.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: