Show HN: Tattoy – a text-based terminal compositor (tattoy.sh)
58 points by tombh 2h ago 14 comments
Show HN:I made a word translation plugin for language learning.
2 points by Mantaa 1d ago 0 comments
Show HN: A terminal emulator in pure PHP
196 aarondf 85 3/21/2025, 5:43:25 PM github.com ↗
It's unusual to see so many negative comments on a new project announcement and yet you persist and even double down with a sarcastic "thanks for your feedback" reply.
I named it screen because the main class is called screen. It was extracted from another library to make maintenance easier. It's not a tool that can ever be used outside of a PHP project, and it has no binary. It's namespaced under SoloTerm.
A nice analogy would be a package named @clerk/auth and then everyone complaining about the package being named auth. I mean it is... but that's not really the full name or how anyone would refer to it.
Most commenters didn't understand any of that nuance and got hung up on a surface level thing that didn't really matter. It was clear to me that the suggestion didn't apply in this case so I thanked them for the feedback. I don't have to take the feedback!
Several other folks commented that it's not really an emulator but rather a renderer. I thought that was a pretty good point and something I was wrong about. So I changed the readme! I thanked them for their feedback as well.
It's no secret that HN commenters lean cynical and can miss the majors for the minors. I just don't want to fight with them! I'm grateful for feedback. Some of it I take and some I completely ignore. As everyone should!
It's more nuanced than just that.
From your README:
> Solo provides a TUI (Text User Interface) that runs multiple processes simultaneously in separate panels, similar to tmux.
You already provide a tool similar to screen. You even call out one of its alternatives! This will lead to confusion.
Further, from another of your comments [0]:
> I use GNU Screen in Solo, where I also use Solo Screen, so I am aware of it.
combined with
> It was extracted from another library to make maintenance easier.
Looking at the code, Solo is the library you extracted it from. You built a technology on top of an existing, well-known project. Then, you extracted some of your code from it and reused the project's name that your tool leverages in that related library.
This is the first way in which your analogy is not sufficient to support your position.
The second is there is no common, well-known, age-old utility called auth in the auth space for people to co-opt.
To quote duskwuff [1] again [2]:
> They're both pieces of software which implement or interact with terminal emulators; I think some deconfliction is warranted here.
Given the context, I don't think namespacing it is a sufficient approach to reducing ambiguity. Especially since screen is often referred to without GNU.
As for this reason:
> I named it screen because the main class is called screen.
Saying you named it screen because the main class was called that isn’t really a justification - especially when you named the class in the first place.
The willful reuse of the utility's name that powers your code and pithy gratitudes all over this thread, to me, send a message of disrespect for the community at large.
[0]: https://news.ycombinator.com/item?id=43439646 [1]: https://news.ycombinator.com/item?id=43439429 [2]: https://news.ycombinator.com/item?id=43439748
Perhaps adding a screenshot or video to the README.md showing what it does could help people understand it better.
Good note on the screenshot. There are some code samples but I'll think if there's a way to add a visual. It's tough cause it's just a library that you consume in PHP! But I'll noodle nonetheless.
Gonna stick with the name screen though
No comments yet
sidenote: screen is a terrible name for this as there is already gnu/screen (colloquially referred to as screen) which has 38 years head start - https://en.wikipedia.org/wiki/GNU_Screen
also til screen is older than me
No comments yet
Help me understand then. What would you call a library that parses ANSI codes, handles scrolling, screen movement, clearing, resets, etc?
While i am a defender of modern (!) php for web applications, this does sound rather weird. But also interesting. Thanks for the link.
I wonder though how "native" this is? Glancing over the docs it seems to be built upon tauri / electron? Not as native as i expected, but probably more native than most people would dare to think about...
I'm delighted that there's some kind of desktop API here. On the one hand, the fact that it's talking with an Electron shell seems sort of magical. But it begs questions like, why wouldn't I just use a fully JS stack? And... since I've never created a graphical app in PHP before, would this be the right time to start?
>> Dialog::new() ->title('Select a file') ->open();
It's an interesting "modern"-ish design choice, but it doesn't feel very PHP-ish. $dialog = new Dialog('title') followed by $dialog->open() would feel more sane.
An advantage of being able to chain calls are fluent expressions that you can return immediately, for example from arrow functions or match expressions, which definitely makes for easier to read code.
new API()->object->method()->subResult
particularly if the API might block. But I can think of a lot of reasons I wouldn't want to see that in my codebase. Usually starting with the fact that
try {
$api = new API();
}
should have a catch after it.
For local stuff, fine, if you want to write that way. I don't find it eminently more readable than seeing a variable created and employed. And I'd like to see the line number the error was thrown on, if I'm reading error logs in production.
Many years ago (see my profile), I wrote a PHP socket server that worked a little bit like Node does. The server itself was a CLI daemon. The webserver sent all the API calls to a normal PHP script that acted as a dispatcher. If the dispatcher saw that the daemon wasn't running, it would call the endpoint itself, block and return a result. If the daemon was running, it would accept an external socket connection to the user and keep itself alive, and open an internal socket to the daemon to route the user's API calls through, which would end up in a queue held by the daemon. The daemon responded to the dispatcher over the internal socket, and the dispatcher sent the results to the user as they came in over the external websocket. Thus it went from one PHP process per call to one PHP process per user, kept alive as long as the daemon was running. I actually think this was niftier in some ways than Node, because no one user could hang the whole server - only their own thread. This was a semi-solution for async calls in PHP.
And, if you want or need to spawn new PHP processes as workers that chew on lots of data, and wait for them to send messages back, you can already do that in a multitude of different ways... as long as the main process waits for them, or else aborts.
In any case, blocking API calls inside a multi-part single line of code are lazy and an invitation to disaster.
[0]: https://gtk.php.net
There's trade offs of course but for things where disk or network is the bottleneck it performs just fine.
I guess maybe if it was PHP8 only...
I did encounter, and try, Linux much sooner. But didn’t really “get it” either at the time. Like, I understood that it was neat and different. I installed Mandriva Linux on my machine when I was 13 or 14 or so, but I was lacking any books or guidance to understand how to do anything aside from opening the GUI programs that was on it.
It would take all until the age of 18, when I started at the university, before I got the help I needed in order to understand Linux and editing config files on Linux and writing my own scripts and programs on Linux.
It was Gentoo for me at the age of 13 that a random Hungarian guy from Finland helped install through SSH.
I did try SUSE around the age of 11, nothing interesting though, the interesting stuff came after Gentoo. :D
I started a very similar project probably ten years ago and just never got it to a very usable state. My idea at the time was based in wanting to be able to write tests for the final output of scripts full of control codes.
I am very excited to see this and to play with it!
It takes some text, outputs it to iTerm and takes a screenshot. Then it takes the same output, runs it through the Screen class, outputs it, and takes a screenshot. Then we compare the screenshots pixel by pixel. So freakin fun
https://www.gnu.org/software/screen/manual/screen.html
Edit: let me actually think a bit before commenting - it would probably just install, but then you run screen and you might or might not get your newly-installed software (so yeah confusion). Not a great first experience at worst
No. It's literally just an in memory buffer that you interact with from PHP.
In Solo (https://github.com/soloterm/solo) we do use GNU screen though.
Unless, this terminal emulator is missing specific features that mean screen doesn't work in it, which would make me feel the definition has been stretched a little here.
Either way, I have to heavily agree with duskwuff's take:
> They're both pieces of software which implement or interact with terminal emulators; I think some deconfliction is warranted here.
Edit: I've learned from a different comment [0] that the latter is indeed the case. This isn't really a terminal emulator.
[0]: https://news.ycombinator.com/item?id=43438797#43439716