absorb is good. I wish it would just rebase for you after creating the fixups but I don't mind the extra step. Have been using this reliably for several years now.
So the commit that you originally got incorrect, is now correct. If a reviewer comes by and reviews your code afresh commit by commit then they won't have to view something you later changed completely.
This is all dependent on how you structure your unit of change and the commits within that.
I like that it's a separate option though, because it's also nice to be able to have the fixup commit show up as a separate change if you're on a forge that has the "here are the changes since you last reviewed" view.
This applies to stacked PR/stacked diff workflows followed by many organizations that aren't on GitHub. These workflows focus on atomic, bisectable commits.
another example: write a change, push, get dinged by linter. You wouldn't want that to be a separate commit. You'd want that to have been part of the original change. So you fix it up and git absorb et voilà!
I also use this when running the big CI suite and I find an edge case that broke something I hadn't thought about. Fix the edge case, add a test. git absorb will put the fix into a fixup! commit and I can amend that with the test to pop it all into the original commit.
I use this thing 50-100 times a day when I'm really churning.
I use fixup! commits a lot on development branches. They allow me to keep the commit history consistent while working, while keeping a clean history for review or in production.
I tend to create fixup! commits on my local branch while I am working through a problem, and have small amends to commits. I squash those commits before opening my changes for review. I want an atomic and descriptive commit history of my changes to help us better understand my original context and intent.
During review, I might have to incorporate some feedback. To avoid "Add changes due to review comments" commits, I add new fixup! commits for minor changes. I believe this makes the review process easier, as it allows the reviewer to easily know what changed, and what they should look at again. I squash those commits before merging my changes onto trunk.
Trunk is never rewritten, even if this means that fixup! commits "leak" into trunk, which has happened to me one or twice.
jj has appeared and kicked off a new round of discussion around git ergonomics (and git history was recently added to git), but I don't think enough people know about git absorb which I use daily at work. My current workflow is to set up the rough series of commits that I want in a pull request, and then as I develop I git absorb the fixes into the appropriate commits as I go.
Oh yes, but for more than performance: I'm always compiling by the time I'm fixing up commits. Patching the source code while compiling it is very UB in terms of build system correctness. I don't know how people can work with that.
Great work, I'm glad I'm not alone in being sick of this app bloat nonsense, for what's otherwise a webpage.
Creating a shortcut on Android devices is very obfuscated to users, so I'm generally not terribly surprised companies prefer apps. But this is a case where you're distributing a password presumably via text alongside a link to an app. This would be an ideal web app! Link to the password page directly and call it done.
/e/OS has a "web apps" section on their app store for Google Maps web, etc. PWAs are fairly easy to use, but I'm not sure what the default Chrome Android, or even vendor Android, does in terms of prompting to create a shortcut and making it discoverable.
Clearly the users aren't being served here though, and I'm not sure what we need to do to help them.
Instead of loading my entire application tree, I only load the subset of DI modules that actually pertain to the module under test. For example, when testing a users API, we now only load the UsersModule and its dependencies.
Adopting the practice from the article will require us to switch from Jest to Vitest, which is a bigger change that we’ll make later this year if Vitest lands in NestJS 12.
A desktop operating system needs to come with a solid, serviceable email client. I consider this non-optional.
Linux is far from having a solid, serviceable email client unless you like using old or haphazardly-designed software and/or you're using an email service from the 1990s. Thunderbird is quirky and its design, even the updated one, leaves a lot to be desired (especially with how the header list is displayed). Geary is far too barebones for my taste. Mailspring never works for me properly (doesn't download all headers/etc, despite acting like it's trying). And all the others are literally made decades ago with no real interest in updating design.
And none of them really work seamlessly with Gmail for mail, contacts, and calendaring. It always takes a lot of effort to really get them to the same state I can get in a matter of seconds using a modern email client like Spark on Windows/MacOS. (no, this is not an ad for Spark, just happens to be what I use currently mainly for the ease of getting up and running...I despise the AI nonsense they're trying to do with it).
Windows 11 feels like an endless string of punches in the face.
Overall, I agree with most of what was written in the article. But I do wonder just how often the author has to tinker in Linux (command-line, config files, etc). Do they lament having that kind of tedium in Linux? Or is it more that they are so used to their workflow in Linux, they no longer see the level of effort because it's now muscle memory?
To a Windows or Mac user who has their workflow embedded in their muscles' memory, Linux would likely also feel like an endless string of punches in the face.
Yep, I know. But sadly right now it's the best email client out there and works the same for me on Windows and MacOS. And it eliminates any friction to getting up and running.
I get that it means I'm trading privacy for convenience, but until there's a better option for me that works perfectly with Gmail, is cross-OS compatible, and has a modern design, I'll be sticking with it, for now.
I've just discovered this concept is called "exclusive arc".
Exclusive arc's coupling of "commentable" to the "page" and "post", doesn't fit best practices for programming languages.
That's always felt like a code smell to me. But I am applying programming best practices to SQL table design, which might be incorrect.
Even with Example 3's use of AI to build it, the topic itself isn't vibecoding and I wouldn't interpret the tag to mean that. We don't tag every post mentioning ripgrep as a dev tool with "rust" because rust is not the topic of discussion.
I wonder if they have the linux side of these boards going so far... I'd love to try one of my immutable Void Linux setups on that device. This could be an always-on computer in my pocket, if I can use something to get bluetooth on the device for my keyboard and audio setup.
I would buy one too, it looks like a fun Linux computer to have around when traveling.
I looked at their developer portal to see if I could contribute, but I really dislike Discord. I think that if they really want to "build it openly" they should use something else.
Because I enjoy spitting into the wind, I'll point out that Zulip offers hosting for open source projects, offers opt-in actually open publishing for channels, and is itself open source (Apache 2)
The board of the Zulip Foundation is the people who were already the leaders of the Zulip project, and the foundation provides a mechanism to replace them. I far prefer this to "we set up a foundation led by some folks who you don't know, but they control it now. Bye!"
I wonder why they removed so much radio technology as opposed to the Zero.
Ah well, it's probably going to be too expensive for me anyway. I'm currently ogling one of those soon-to-be-Kickstartered M5Stack thingies. Granted, way less powerful, but at least more buttons and LoRa is only one additional module away.
(I have up to now owned neither a Flipper nor an M5Stack device)
Granted, it's a toy. But I actually could make use of the IR Tx in my home, use it as a music player, tinker with it, and I'm genuinely curious if LoRa messaging is a good option to call the kids home without having to give them phones. Walkie-Talkie range is too low for that.
I gave a conference talk at SELF one year about immutable virtual machines. I wasn't as far along in my journey then as I am now, but I still use the model, especially for my OpenBSD infrastructure (where I don't trust the filesystem to survive a power event):
Base qcow2 file
Use an overlay
On VM start, remove and recreate the overlay every time
If it booted once, it'll boot the next time exactly the same way. Couple with autoinstallation and other automation before cutting the golden image for a given system. This lets me test the golden image before switching it over, and reduce how much I need to back up.
On metal, I've evolved my understanding. I used to on my laptop just do ZFS root (still do that on Void Musl) and have snapshots available, but my desktops and laptops too often need mutable state. Firefox configs in particular are dangerous and reject declarative setups. So I don't. I leave the immutable setups to my "worker" systems that perform other functions, such as my NAS. For that there are two models.
One of the Void maintainers uses a simple suite to manage immutable Void setups. Install once, update forever... when you want to. https://github.com/ahesford/vcluster is that approach.
It doesn't really work for me, where I want even less customization. I've got some clusters that are recreated from scratch on a regular basis with autoinstallers, and that works ok.... it's not the best but allows me to refresh the gear without an update, just by re-asserting the Void setup. Also lets me change from musl to glibc or back depending on how my expressed needs correlate with the availability of the platform.
So my newer approach which my NAS (limitedly stateful, even if it's inherently stateful) uses is just booting from a USB stick (paired up actually so I can switch A/B by editing EFI vars) running hrmpf -- HEAVILY customized before I boot from it. My own user, for example. My own ssh keys. My own programs and ZFS already enabled and ready and iscsi (maybe soon nvme-of?) already set up. Then upgrading is writing a new hrmpf image to a USB drive, swapping them out, and rebooting the box during a service window.
The best trick is making sure anything that needs to be dynamic is reduced to a configuration file of some sort and mounted in, so the immutable part is as great as I can manage. This however takes some finesse, there is no one-size-fits-all approach here. Some workloads simply reject immutability.
Though it has been my observation that most workloads reject immutability before a point. An openbsd pledge() syscall cuts off some program capabilities after you needed it up front (such as opening a file in cat, only happens once at the beginning). You can phase immutability in. Start mutable, get a lot done, and then set your marker in the bits and go immutable from that point forward. You can prepare much of your later-immutable-environment if you have the hooks in place to finish any required setup after your golden image.
There is other work I've done with immutable systems and Void, not all of it as ready to publish as what I've written here.
Tell me more please! I use OpenBSD on the desktop these days instead of Void, but I still keep it around on another machine to stay up to date on the distro. Is this something you built yourself or is there an "immutable Void" project out there?
I’ve felt that Chimera is Void Linux's sibling in this space. I’m curious: what feels substantially different about Chimera's stack, like the build system and init, that makes it appeal to you over xbps and daemontools?
I really enjoyed my time on Void even with some of the extra chores of having to step in and help keep packages up to date. Plus xpbs-src is very flexible. One could just use void and its base packages as a platform and install another package manager like lix, linux brew, or guix on top of it. Chimera has had my attention for a bit but haven't tried it yet.
I've tried something vaguely similar, but I found interdiff quite difficult to do with a vim workflow to see the diff. How does one best leverage the range diff output?
I was diagnosed with bipolar 2 this year after a couple years of symptom escalation.
I've been disappointed with the tracking available to me in most of the recommended apps, so I've been building my own (which could in itself be a bipolar project). I've been experiencing rapid/mixed cycling which is very difficult and doesn't track very well in the common apps which just want a daily number between "sad" and "happy" it's not easy to visualise "my thoughts were racing and I was full of energy but I was really really sad".
It's been really interesting learning about the current state of "web on mobile" technologies. Capacitor can go surprisingly far, even interfacing with the health API via a plugin to grab sleep data. The whole thing is written in Clojurescript, and it's been fun flexing my frontend skills again which have gotten rusty.
Konsta UI and Ionic are really interesting mobile UI projects. It's great building something that does feel fairly native and calls out to native UI such as date pickers where it makes sense.
I did have a play with ClojureDart to build it with Flutter, as the current Bipolar UK app is, but I found myself quite lost compared to the web knowledge I already had. I'm also really unhappy with the results of flutter apps I've used, but that could be because they were bad. For example flutter has it's own date picker which doesn't feel as smooth as the native android one.
Ah, I forgot to mention this in the post... For now probably not, as supporting one init system is enough work for us Void maintainers. I'll at some point publish some scripts to use nitro on Void, so you can convert it on your own account.
It's not really; something can be done "on one's own account" or "of one's own accord", but I don't think these have identical meaning. Individually, each word has meanings that the other doesn't (eg an "account" can be someone's telling or recollection, and "accord" can be an agreement).
I've understood the difference for these particular phrases to be that "account" is talking about to whom cost/benefit applies whereas "accord" is talking about where authority comes from, I.e. "of their own accord" means they chose to do it themselves, "on their own account" (or "on account of themselves" which is probably the more correct/idiomatic way of phrasing it -- maybe not though, that latter form is probably for where the subject is a reason, ugh) means they did it for their own benefit.
Of course, nobody speaks English perfectly, pretty much by definition, so there's always leeway - for better or worse.
It actually means (roughly) "you do it for your own benefit", but I think getting pulled up for this would be unusual, and native speakers are prone to the same mistake. FWIW I think it's clear from context what you actually meant, and for English speakers that's usually good enough.
I got a bit nerd sniped here because I thought it was accord as well.
Looking it up apparently it's "of one's own accord" and "on one's own account". I had no idea, and even as a native speaker, I'm not entirely sure why, and what the difference really is. They seem to be completely interchangeable phrases.
They seem to be completely interchangeable phrases.
Not quite; as the examples you've linked show, "of ones own accord" means "of ones own volition" whereas "on ones own account" means "for ones own benefit". You can do something of your own volition but for reasons other than it benefiting yourself, so that would be your own accord but not your own account.
This is a really well written article. I use fugitive in a similar way, the per-line staging feature is a much needed supplement to the horrible UX of git add -p.
Regarding merge conflicts I reserve the full blown git mergetool for only the most complicated merge conflicts, the :G mergetool approach for just populating the quickfixlist with merge conflict markers (then manually editing) seems favorable to me.
Actually coming to think about it, I almost always prefer this approach and I have solved my fair share of merge conflicts in the past years. Does anyone (using vim or not) even enjoy using 3-way diff solvers? To me it's always so confusing which side is which, as it is inverted between merge and rebase, plus I can usually understand the context the fastest if I just see everything together.
vim-conflicted provides a very nice interface for resolving merge conflicts. It's dependent on fugitive, and solves the problem of understanding what changed upstream that you need to incorporate into your patch's changes.
per-line staging feature is a much needed supplement to the horrible UX of git add -p
git add -e (or, of course, git stage -e) provides the real per-line staging – it opens the unstaged diffs in your editor. Of course, vim-fugitive probably has a better UX at least until one gets used to the interface provided by git add -e.
I would argue that git add -e has even worse UX than git add -p as you are literally editing the diff directly. There is a reason it got an entire warning section on its own in the man page.
Granted, it's faster than splitting a hunk repeatedly, but you gotta ask yourself if you are seriously considering it as an alternative to real per-line staging, when even kernel maintainers have to brag about being able to use the damn thing:
I want a Linkedin skill badge for “can edit diff files by hand and have them still work”
Of course Greg hand-crafting additions is a bit more risky operation than just sculpting away lines from the staging diff, but man it still sounds like you are just constantly one typo away from fuzzy-testing a new CVE in git's diff parser. Also you are really doing the inverse of per-line staging, you are removing lines until you are left with the lines you want to stage, which can take considerably longer than per-line staging.
I haven't used this feature of Postgres in production before, I'd be curious what other use-cases people have found for them (that are actively used)?
I suppose from reading the post and looking online that it's possible for messages to be lost? i.e. if a client isn't connected / listening to a NOTIFY, then the message is just lost?
I've used it in various situations to hook it into other systems to avoid querying for new rows repeatedly for example. One can even combine this with triggers and notify under certain conditions and maybe even mention what has happened for example that "row with ID X has been updated".
So a piece of software would start, check the database and do it's thing, then, would only continue to do its thing if a notify comes in, otherwise it can idle, instead of querying all the time.
We use it for webhooks. We interact with a third-party which may not have the data right away, and will instead call a webhook. We save the data to cache it for later, and as part of that we trigger a notify that allows the original caller that was requesting the data to await the update to that row.
I used it about a decade ago before things like RabbitMQ were in vogue. We had a bunch of workers that sat and listened for notifications. The web interface would insert rows into the work queue, the workers got notified, and then updated the work rows with a success/fail. Worked awesome and meant that the crusty old PHP web app didn't need any new dependencies added to it.
It's super useful to refresh configuration between multiple system.
We at https://hanami.run have a mail server and a web app. user use the web app to configure their email forwarding rule. the mail server listen to Postgres to refresh its configuration.
Losing message is totally fine in our case because upon restarting, the mail server query Postgres and get fresh data already.
As in, listen/notify is to notify about changes to do something. If a client isn't connected, then upon re-connectiong they know what they have to do(reload the whole configuration).
Same as @tonyarkles noted below: I use them for queues, which saves adding a whole new system.
In addition I used them to monitor balances of users. If the balance gets under a certain threshold a trigger fires the notify, and some service picks that up.
In both cases the payload is empty. The receiver of the notify will figure out what needs to happen, and the receivers are also woken up every once in a while with a timer, so it doesn't matter much if a notify gets lost.
Works very well, super easy to test, no dependencies to maintain.
I've noticed the same issue with Electron apps on my low RAM devices. Anything with 4GB or less of RAM doesn't allow you to run more than 2 instances of the programs, without chugging into swap space or worse, oom-killing.
Particularly worrying is most of my messaging apps are exactly like that: Riot/Element, FB Messenger, WhatsApp, Telegram (this last one is actually pretty optimized and doesn't eat too much). Long gone are the days where an XMPP bridge would solve the issue, as most of the content is now images, audio messages, animated GIFs, emojis and other rich content.
Thanks for the article, at least I know that i can replace one of the culprits with a daemonized, non-Electron app and just use the phone as a remote control.
Long gone are the days where an XMPP bridge would solve the issue, as most of the content is now images, audio messages, animated GIFs, emojis and other rich content.
I'm not sure what you mean. Most XMPP clients today (like Conversations, Dino, etc.) gracefully handle all of the items you mentioned, and with much less resources than a full web browser would require. I definitely recommend XMPP bridges when possible where the only alternative is an "app" that is really a full web browser.
Of those listed, I think Riot will maybe disappear at some point. Riot has (amazingly) managed to have native desktop clients pop up, Quarternion, gomatrix and nheko are all packaged for my Linux distribution.
I understand the desire to use something browser-ish and cross-platform. I don't fully understand why Electron (hundreds of mb footprint) is so popular over Sciter (5mb footprint).
Electron is fully free, Sciter is closed-source with a Kickstarter campaign in progress to open-source it.
For the large companies, the price of something like Sciter should be a non-issue. If I were reviewing a proposal to use it, though, I'd be asking about security review and liability: HTML/CSS/JS have proven to be hard to get secure, Electron leverages the sugar-daddy of Google maintaining Chrome with security fixes, what is the situation with Sciter like?
Ideally, the internal review would go "okay, but if we only connect to our servers, and we make sure we're not messing up TLS/HTTPS, then the only attack model is around user-data from other users being rendered in these contexts, and we have to have corner-case testing there no matter which engine we use, to make sure there are no leaks, so this is all manageable". But I can see that "manageable" might not be enough to overcome the initial knee-jerk reactions.
Isn’t the reason that XMPP isn’t useful more to do with these services wanting to maintain walled gardens? And further, isn’t that a result of the incentives in a world of “free” services?
I found that, for me, the most important thing was simple. I obsessed over all sorts of tools, vimwiki, org mode, etc. In the end I realized the most important thing to focus on was portability. I need a system that works anywhere, and I can trust will be around for a long time.
My basic system is .md files in SyncThing. On my desktop I edit them with Vim, on my phone I edit them with Markor. I don't organize particularly. I group some things into top level pieces (e.g. technology, home, etc.) but there's no real system.
That's more or less what I do. I have been planning to add them to SyncThing too as currently they are spread between different systems. I just have a directory with a bunch of plain text files. Once a file gets beyond a paragraph or two, or just a collection of links, I start writing it in Markdown. At various points I've felt like I should be doing more, but every alternative system I've looked at feels too complicated. The important thing for me is writing, and there should be as little friction as possible (so it doesn't get much easier than simply opening my text editor) and with plain text I'm free to format it however I like (though I do try to keep it organised). Whenever I want to look something up I just grep the directory.
I saw the other post about 'just forgetting things', but I don't think that would ever work for me. A lot of my notes are on how I solved a problem, or compiling a bunch of separate material into something concise and coherent. I can't just 'look that up' again next time I run into it, unless I want to repeat the whole process again. And really, the whole point of writing notes for me is to get things out of my head so that I can focus on other things. I don't refer back to my notes often, but when I do they're a life saver.
I do often write paper notes too, but generally only for quick to do tasks or temporary lists, and sometimes while I'm trying to conceptualise an issue. I think they're great for that. Ultimately, the less specific tools I have, the better. Otherwise I might need to start writing notes on how I use my note taking tools!
The most common complaint I hear is headaches. I'm sure there's plenty of people who are very light sensitive and do get headaches, but most people should try turning the brightness down before putting themselves into that category.
My wife was able to buy a monitor with someone else's money, so I recommended she get the LG Ultrafine 5k. It's an amazing monitor, and way too bright at default settings. We both would get headaches from using it until we knocked the brightness down a notch or two.
yeah I also discovered that with my new monitor, it actually improved a bunch when I changed to backlight color from cold to warm, but it skews color correctness on it.
Every time I have tried adjusting a modern monitor for comfort, I've put the brightness setting the lowest value offered by the firmware and it's still too bright.
its not that someone does or does not have "special eyes" its a what are you optimizing for as always, because if you go look at the stats in a different direction using a cool colored backlight, light themes increase eyestrain and mess with your sleep cycles due to artificial blue light exposure, dark schemes reduce that.
Light schemes are less power efficient on modern display panels so if you are optimizing for battery life guess what dark theme wins.
Then when you get to "special eyes" there are a lot of people who have Myopia or Astigmatism, which dark themes can produce halation, chances are light themes are better for you there.
If you are trying to present on a large screen having a theme that is somewhere in the middle, and a little darker for dark rooms and a little lighter for light rooms wins.
My point is more or less there is a ton of nuance here where saying "SEE SEE SEE SEE SEE SCIENCE PROVES MY PERSONAL PREFERENCES RIGHT" is wrong, and the author honestly skips over all of that to justify their own preferences for some reason.
My point is more or less there is a ton of nuance here where saying “SEE SEE SEE SEE SEE SCIENCE PROVES MY PERSONAL PREFERENCES RIGHT” is wrong, and the author honestly skips over all of that to justify their own preferences for some reason.
"I'm right because science" is a tactic to insulate against criticism, it preemptively accuses you of "denying science" if you dare to disagree.
absorb is good. I wish it would just rebase for you after creating the fixups but I don't mind the extra step. Have been using this reliably for several years now.
I believe you're looking for the
-rflag?Why would you rewrite history just to address review feedback? That seems confusing.
So the commit that you originally got incorrect, is now correct. If a reviewer comes by and reviews your code afresh commit by commit then they won't have to view something you later changed completely.
This is all dependent on how you structure your unit of change and the commits within that.
I like that it's a separate option though, because it's also nice to be able to have the fixup commit show up as a separate change if you're on a forge that has the "here are the changes since you last reviewed" view.
This applies to stacked PR/stacked diff workflows followed by many organizations that aren't on GitHub. These workflows focus on atomic, bisectable commits.
another example: write a change, push, get dinged by linter. You wouldn't want that to be a separate commit. You'd want that to have been part of the original change. So you fix it up and
git absorbet voilà!I also use this when running the big CI suite and I find an edge case that broke something I hadn't thought about. Fix the edge case, add a test.
git absorbwill put the fix into afixup!commit and I can amend that with the test to pop it all into the original commit.I use this thing 50-100 times a day when I'm really churning.
I use
fixup!commits a lot on development branches. They allow me to keep the commit history consistent while working, while keeping a clean history for review or in production.I tend to create
fixup!commits on my local branch while I am working through a problem, and have small amends to commits. I squash those commits before opening my changes for review. I want an atomic and descriptive commit history of my changes to help us better understand my original context and intent.During review, I might have to incorporate some feedback. To avoid "Add changes due to review comments" commits, I add new
fixup!commits for minor changes. I believe this makes the review process easier, as it allows the reviewer to easily know what changed, and what they should look at again. I squash those commits before merging my changes onto trunk.Trunk is never rewritten, even if this means that
fixup!commits "leak" into trunk, which has happened to me one or twice.jj has appeared and kicked off a new round of discussion around git ergonomics (and git history was recently added to git), but I don't think enough people know about git absorb which I use daily at work. My current workflow is to set up the rough series of commits that I want in a pull request, and then as I develop I git absorb the fixes into the appropriate commits as I go.
I'm kinda hoping absorb can leverage history somehow to speed up the pairing performance. It would be a great outcome.
Oh yes, but for more than performance: I'm always compiling by the time I'm fixing up commits. Patching the source code while compiling it is very UB in terms of build system correctness. I don't know how people can work with that.
I use git-revise for the same reason.
Great work, I'm glad I'm not alone in being sick of this app bloat nonsense, for what's otherwise a webpage.
Creating a shortcut on Android devices is very obfuscated to users, so I'm generally not terribly surprised companies prefer apps. But this is a case where you're distributing a password presumably via text alongside a link to an app. This would be an ideal web app! Link to the password page directly and call it done.
/e/OS has a "web apps" section on their app store for Google Maps web, etc. PWAs are fairly easy to use, but I'm not sure what the default Chrome Android, or even vendor Android, does in terms of prompting to create a shortcut and making it discoverable.
Clearly the users aren't being served here though, and I'm not sure what we need to do to help them.
This inspired me to turn Fable on my e2e tests for a NestJS app. Turns out I can cut run time by 60% by changing module loading!
Changing module loading from what, to what? Are you using the strategy from the article? What's that in absolute numbers?
Instead of loading my entire application tree, I only load the subset of DI modules that actually pertain to the module under test. For example, when testing a users API, we now only load the UsersModule and its dependencies.
Adopting the practice from the article will require us to switch from Jest to Vitest, which is a bigger change that we’ll make later this year if Vitest lands in NestJS 12.
Linux is far from having a solid, serviceable email client unless you like using old or haphazardly-designed software and/or you're using an email service from the 1990s. Thunderbird is quirky and its design, even the updated one, leaves a lot to be desired (especially with how the header list is displayed). Geary is far too barebones for my taste. Mailspring never works for me properly (doesn't download all headers/etc, despite acting like it's trying). And all the others are literally made decades ago with no real interest in updating design.
And none of them really work seamlessly with Gmail for mail, contacts, and calendaring. It always takes a lot of effort to really get them to the same state I can get in a matter of seconds using a modern email client like Spark on Windows/MacOS. (no, this is not an ad for Spark, just happens to be what I use currently mainly for the ease of getting up and running...I despise the AI nonsense they're trying to do with it).
Overall, I agree with most of what was written in the article. But I do wonder just how often the author has to tinker in Linux (command-line, config files, etc). Do they lament having that kind of tedium in Linux? Or is it more that they are so used to their workflow in Linux, they no longer see the level of effort because it's now muscle memory?
To a Windows or Mac user who has their workflow embedded in their muscles' memory, Linux would likely also feel like an endless string of punches in the face.
Evolution feels like a "standard" email client to me, and works well enough for my very basic needs. Where does it fall on the spectrum here?
FYI, Spark, like the modern Outlook webapp, processes your mail on "cloud". Spark is AWS, us-east-01.
Yep, I know. But sadly right now it's the best email client out there and works the same for me on Windows and MacOS. And it eliminates any friction to getting up and running.
I get that it means I'm trading privacy for convenience, but until there's a better option for me that works perfectly with Gmail, is cross-OS compatible, and has a modern design, I'll be sticking with it, for now.
I've just discovered this concept is called "exclusive arc".
Exclusive arc's coupling of "commentable" to the "page" and "post", doesn't fit best practices for programming languages. That's always felt like a code smell to me. But I am applying programming best practices to SQL table design, which might be incorrect.
The author linked a stack exchange post and I discovered GitLab's contributor guide to polymorphic associations which provides interesting arguments on the topic.
Even with Example 3's use of AI to build it, the topic itself isn't vibecoding and I wouldn't interpret the tag to mean that. We don't tag every post mentioning ripgrep as a dev tool with "rust" because rust is not the topic of discussion.
ripgrep isn't part of the final product, LLM-barfed code is.
I would buy one of these. Or three.
I wonder if they have the linux side of these boards going so far... I'd love to try one of my immutable Void Linux setups on that device. This could be an always-on computer in my pocket, if I can use something to get bluetooth on the device for my keyboard and audio setup.
I would buy one too, it looks like a fun Linux computer to have around when traveling.
I looked at their developer portal to see if I could contribute, but I really dislike Discord. I think that if they really want to "build it openly" they should use something else.
Because I enjoy spitting into the wind, I'll point out that Zulip offers hosting for open source projects, offers opt-in actually open publishing for channels, and is itself open source (Apache 2)
Unfortunately the people behind Zulip were bought by Anthropic. (https://lobste.rs/s/2whryd/announcing_zulip_foundation)
…and they’re transferring the project to the non-profit foundation they announced so I don’t see the issue here?
https://lobste.rs/s/2whryd/announcing_zulip_foundation#c_wa5dms
The board of the Zulip Foundation is the people who were already the leaders of the Zulip project, and the foundation provides a mechanism to replace them. I far prefer this to "we set up a foundation led by some folks who you don't know, but they control it now. Bye!"
Zulip is amazing. I promote it everywhere I can.
I wonder why they removed so much radio technology as opposed to the Zero.
Ah well, it's probably going to be too expensive for me anyway. I'm currently ogling one of those soon-to-be-Kickstartered M5Stack thingies. Granted, way less powerful, but at least more buttons and LoRa is only one additional module away.
(I have up to now owned neither a Flipper nor an M5Stack device)
What are you likely to use it for? I find the use cases to be rather limited for my day to day.
Granted, it's a toy. But I actually could make use of the IR Tx in my home, use it as a music player, tinker with it, and I'm genuinely curious if LoRa messaging is a good option to call the kids home without having to give them phones. Walkie-Talkie range is too low for that.
Off-topic: I would love to hear about your immutable Void Linux setups, if you have written about it anywhere!
I gave a conference talk at SELF one year about immutable virtual machines. I wasn't as far along in my journey then as I am now, but I still use the model, especially for my OpenBSD infrastructure (where I don't trust the filesystem to survive a power event):
If it booted once, it'll boot the next time exactly the same way. Couple with autoinstallation and other automation before cutting the golden image for a given system. This lets me test the golden image before switching it over, and reduce how much I need to back up.
On metal, I've evolved my understanding. I used to on my laptop just do ZFS root (still do that on Void Musl) and have snapshots available, but my desktops and laptops too often need mutable state. Firefox configs in particular are dangerous and reject declarative setups. So I don't. I leave the immutable setups to my "worker" systems that perform other functions, such as my NAS. For that there are two models.
One of the Void maintainers uses a simple suite to manage immutable Void setups. Install once, update forever... when you want to. https://github.com/ahesford/vcluster is that approach.
It doesn't really work for me, where I want even less customization. I've got some clusters that are recreated from scratch on a regular basis with autoinstallers, and that works ok.... it's not the best but allows me to refresh the gear without an update, just by re-asserting the Void setup. Also lets me change from musl to glibc or back depending on how my expressed needs correlate with the availability of the platform.
So my newer approach which my NAS (limitedly stateful, even if it's inherently stateful) uses is just booting from a USB stick (paired up actually so I can switch A/B by editing EFI vars) running hrmpf -- HEAVILY customized before I boot from it. My own user, for example. My own ssh keys. My own programs and ZFS already enabled and ready and iscsi (maybe soon nvme-of?) already set up. Then upgrading is writing a new hrmpf image to a USB drive, swapping them out, and rebooting the box during a service window.
The best trick is making sure anything that needs to be dynamic is reduced to a configuration file of some sort and mounted in, so the immutable part is as great as I can manage. This however takes some finesse, there is no one-size-fits-all approach here. Some workloads simply reject immutability.
Though it has been my observation that most workloads reject immutability before a point. An openbsd pledge() syscall cuts off some program capabilities after you needed it up front (such as opening a file in cat, only happens once at the beginning). You can phase immutability in. Start mutable, get a lot done, and then set your marker in the bits and go immutable from that point forward. You can prepare much of your later-immutable-environment if you have the hooks in place to finish any required setup after your golden image.
There is other work I've done with immutable systems and Void, not all of it as ready to publish as what I've written here.
Tell me more please! I use OpenBSD on the desktop these days instead of Void, but I still keep it around on another machine to stay up to date on the distro. Is this something you built yourself or is there an "immutable Void" project out there?
https://lobste.rs/s/fxqjqu/flipper_one_we_need_your_help#c_tccjmc
I’ve felt that Chimera is Void Linux's sibling in this space. I’m curious: what feels substantially different about Chimera's stack, like the build system and init, that makes it appeal to you over xbps and daemontools?
I really enjoyed my time on Void even with some of the extra chores of having to step in and help keep packages up to date. Plus xpbs-src is very flexible. One could just use void and its base packages as a platform and install another package manager like lix, linux brew, or guix on top of it. Chimera has had my attention for a bit but haven't tried it yet.
I've tried something vaguely similar, but I found interdiff quite difficult to do with a vim workflow to see the diff. How does one best leverage the range diff output?
I was diagnosed with bipolar 2 this year after a couple years of symptom escalation.
I've been disappointed with the tracking available to me in most of the recommended apps, so I've been building my own (which could in itself be a bipolar project). I've been experiencing rapid/mixed cycling which is very difficult and doesn't track very well in the common apps which just want a daily number between "sad" and "happy" it's not easy to visualise "my thoughts were racing and I was full of energy but I was really really sad".
It's been really interesting learning about the current state of "web on mobile" technologies. Capacitor can go surprisingly far, even interfacing with the health API via a plugin to grab sleep data. The whole thing is written in Clojurescript, and it's been fun flexing my frontend skills again which have gotten rusty.
Konsta UI and Ionic are really interesting mobile UI projects. It's great building something that does feel fairly native and calls out to native UI such as date pickers where it makes sense.
I did have a play with ClojureDart to build it with Flutter, as the current Bipolar UK app is, but I found myself quite lost compared to the web knowledge I already had. I'm also really unhappy with the results of flutter apps I've used, but that could be because they were bad. For example flutter has it's own date picker which doesn't feel as smooth as the native android one.
Hi Leah! Do you think we're likely to get nitro on Void as an option? I can imagine that being a huge undertaking.
Ah, I forgot to mention this in the post... For now probably not, as supporting one init system is enough work for us Void maintainers. I'll at some point publish some scripts to use nitro on Void, so you can convert it on your own account.
You mean accord, right?
“On your own account” is, if not perfectly idiomatic in this usage, at least reasonably so.
perfectly valid, but then it's not pid 1.
Account is not used in a technical way here. It's unrelated to Unix users. It's literally interchangeable with accord.
It's not really; something can be done "on one's own account" or "of one's own accord", but I don't think these have identical meaning. Individually, each word has meanings that the other doesn't (eg an "account" can be someone's telling or recollection, and "accord" can be an agreement).
I've understood the difference for these particular phrases to be that "account" is talking about to whom cost/benefit applies whereas "accord" is talking about where authority comes from, I.e. "of their own accord" means they chose to do it themselves, "on their own account" (or "on account of themselves" which is probably the more correct/idiomatic way of phrasing it -- maybe not though, that latter form is probably for where the subject is a reason, ugh) means they did it for their own benefit.
Of course, nobody speaks English perfectly, pretty much by definition, so there's always leeway - for better or worse.
Not a native speaker, but doesn't "own account" mean "you do it and are responsible for it yourself"?
Yep this made complete sense to me, a native speaker, and the alternatives proposed would be more confusing.
It actually means (roughly) "you do it for your own benefit", but I think getting pulled up for this would be unusual, and native speakers are prone to the same mistake. FWIW I think it's clear from context what you actually meant, and for English speakers that's usually good enough.
I got a bit nerd sniped here because I thought it was accord as well.
Looking it up apparently it's "of one's own accord" and "on one's own account". I had no idea, and even as a native speaker, I'm not entirely sure why, and what the difference really is. They seem to be completely interchangeable phrases.
Sources:
Not quite; as the examples you've linked show, "of ones own accord" means "of ones own volition" whereas "on ones own account" means "for ones own benefit". You can do something of your own volition but for reasons other than it benefiting yourself, so that would be your own accord but not your own account.
Huh, TIL. I'm not a native user of English either (like the OP) so, sorry for the confusion.
This is a really well written article. I use fugitive in a similar way, the per-line staging feature is a much needed supplement to the horrible UX of
git add -p.Regarding merge conflicts I reserve the full blown
git mergetoolfor only the most complicated merge conflicts, the :G mergetool approach for just populating the quickfixlist with merge conflict markers (then manually editing) seems favorable to me.Actually coming to think about it, I almost always prefer this approach and I have solved my fair share of merge conflicts in the past years. Does anyone (using vim or not) even enjoy using 3-way diff solvers? To me it's always so confusing which side is which, as it is inverted between merge and rebase, plus I can usually understand the context the fastest if I just see everything together.
vim-conflicted provides a very nice interface for resolving merge conflicts. It's dependent on fugitive, and solves the problem of understanding what changed upstream that you need to incorporate into your patch's changes.
git add -e(or, of course,git stage -e) provides the real per-line staging – it opens the unstaged diffs in your editor. Of course, vim-fugitive probably has a better UX at least until one gets used to the interface provided bygit add -e.I think of
git add -pfor per-hunk staging.I would argue that
git add -ehas even worse UX thangit add -pas you are literally editing the diff directly. There is a reason it got an entire warning section on its own in the man page.Granted, it's faster than splitting a hunk repeatedly, but you gotta ask yourself if you are seriously considering it as an alternative to real per-line staging, when even kernel maintainers have to brag about being able to use the damn thing:
Of course Greg hand-crafting additions is a bit more risky operation than just sculpting away lines from the staging diff, but man it still sounds like you are just constantly one typo away from fuzzy-testing a new CVE in git's diff parser. Also you are really doing the inverse of per-line staging, you are removing lines until you are left with the lines you want to stage, which can take considerably longer than per-line staging.
Oh I have no point in favour of the UX of
git add -e.I was only pointing out that hunks quite often fail to achieve per-line granularity.
What a coincidence! I discovered Grist just this weekend. I even opened a PR to fix a bug I ran into.
Being able to fix a bug I'd found was really wonderful. Exactly the kind of experience I want from using open source self hosted software.
I haven't used this feature of Postgres in production before, I'd be curious what other use-cases people have found for them (that are actively used)?
I suppose from reading the post and looking online that it's possible for messages to be lost? i.e. if a client isn't connected / listening to a
NOTIFY, then the message is just lost?Interesting. Thanks for sharing.
I've used it in various situations to hook it into other systems to avoid querying for new rows repeatedly for example. One can even combine this with triggers and notify under certain conditions and maybe even mention what has happened for example that "row with ID X has been updated".
So a piece of software would start, check the database and do it's thing, then, would only continue to do its thing if a notify comes in, otherwise it can idle, instead of querying all the time.
We use it for webhooks. We interact with a third-party which may not have the data right away, and will instead call a webhook. We save the data to cache it for later, and as part of that we trigger a notify that allows the original caller that was requesting the data to await the update to that row.
I used it about a decade ago before things like RabbitMQ were in vogue. We had a bunch of workers that sat and listened for notifications. The web interface would insert rows into the work queue, the workers got notified, and then updated the work rows with a success/fail. Worked awesome and meant that the crusty old PHP web app didn't need any new dependencies added to it.
It's super useful to refresh configuration between multiple system.
We at https://hanami.run have a mail server and a web app. user use the web app to configure their email forwarding rule. the mail server listen to Postgres to refresh its configuration.
Losing message is totally fine in our case because upon restarting, the mail server query Postgres and get fresh data already.
As in, listen/notify is to notify about changes to do something. If a client isn't connected, then upon re-connectiong they know what they have to do(reload the whole configuration).
Same as @tonyarkles noted below: I use them for queues, which saves adding a whole new system.
In addition I used them to monitor balances of users. If the balance gets under a certain threshold a trigger fires the notify, and some service picks that up.
In both cases the payload is empty. The receiver of the notify will figure out what needs to happen, and the receivers are also woken up every once in a while with a timer, so it doesn't matter much if a notify gets lost.
Works very well, super easy to test, no dependencies to maintain.
I've noticed the same issue with Electron apps on my low RAM devices. Anything with 4GB or less of RAM doesn't allow you to run more than 2 instances of the programs, without chugging into swap space or worse, oom-killing.
Particularly worrying is most of my messaging apps are exactly like that: Riot/Element, FB Messenger, WhatsApp, Telegram (this last one is actually pretty optimized and doesn't eat too much). Long gone are the days where an XMPP bridge would solve the issue, as most of the content is now images, audio messages, animated GIFs, emojis and other rich content.
Thanks for the article, at least I know that i can replace one of the culprits with a daemonized, non-Electron app and just use the phone as a remote control.
As far as I am aware, Telegram is not Electron, it is actually a Qt based app.
I'm not sure what you mean. Most XMPP clients today (like Conversations, Dino, etc.) gracefully handle all of the items you mentioned, and with much less resources than a full web browser would require. I definitely recommend XMPP bridges when possible where the only alternative is an "app" that is really a full web browser.
Of those listed, I think Riot will maybe disappear at some point. Riot has (amazingly) managed to have native desktop clients pop up, Quarternion, gomatrix and nheko are all packaged for my Linux distribution.
I understand the desire to use something browser-ish and cross-platform. I don't fully understand why Electron (hundreds of mb footprint) is so popular over Sciter (5mb footprint).
Electron is fully free, Sciter is closed-source with a Kickstarter campaign in progress to open-source it.
For the large companies, the price of something like Sciter should be a non-issue. If I were reviewing a proposal to use it, though, I'd be asking about security review and liability: HTML/CSS/JS have proven to be hard to get secure, Electron leverages the sugar-daddy of Google maintaining Chrome with security fixes, what is the situation with Sciter like?
Ideally, the internal review would go "okay, but if we only connect to our servers, and we make sure we're not messing up TLS/HTTPS, then the only attack model is around user-data from other users being rendered in these contexts, and we have to have corner-case testing there no matter which engine we use, to make sure there are no leaks, so this is all manageable". But I can see that "manageable" might not be enough to overcome the initial knee-jerk reactions.
I use Dino on desktop to replace the bloated Discord & WhatsApp clients, and it works fine (with inline images, file sharing, etc working too).
Disclaimer: I did, however, write the WhatsApp bridge :p
Isn’t the reason that XMPP isn’t useful more to do with these services wanting to maintain walled gardens? And further, isn’t that a result of the incentives in a world of “free” services?
I stumbled across this when an implementation was created for clojure.
I'm curious to look further into Branca to see to their suitability as a JWT replacement, due to the many well known issues with JWT.
this is only for symmetric encryption
I found that, for me, the most important thing was simple. I obsessed over all sorts of tools, vimwiki, org mode, etc. In the end I realized the most important thing to focus on was portability. I need a system that works anywhere, and I can trust will be around for a long time.
My basic system is .md files in SyncThing. On my desktop I edit them with Vim, on my phone I edit them with Markor. I don't organize particularly. I group some things into top level pieces (e.g. technology, home, etc.) but there's no real system.
That's more or less what I do. I have been planning to add them to SyncThing too as currently they are spread between different systems. I just have a directory with a bunch of plain text files. Once a file gets beyond a paragraph or two, or just a collection of links, I start writing it in Markdown. At various points I've felt like I should be doing more, but every alternative system I've looked at feels too complicated. The important thing for me is writing, and there should be as little friction as possible (so it doesn't get much easier than simply opening my text editor) and with plain text I'm free to format it however I like (though I do try to keep it organised). Whenever I want to look something up I just grep the directory.
I saw the other post about 'just forgetting things', but I don't think that would ever work for me. A lot of my notes are on how I solved a problem, or compiling a bunch of separate material into something concise and coherent. I can't just 'look that up' again next time I run into it, unless I want to repeat the whole process again. And really, the whole point of writing notes for me is to get things out of my head so that I can focus on other things. I don't refer back to my notes often, but when I do they're a life saver.
I do often write paper notes too, but generally only for quick to do tasks or temporary lists, and sometimes while I'm trying to conceptualise an issue. I think they're great for that. Ultimately, the less specific tools I have, the better. Otherwise I might need to start writing notes on how I use my note taking tools!
In before someone claims they've got special eyes which are different from everyone else's.
The most common complaint I hear is headaches. I'm sure there's plenty of people who are very light sensitive and do get headaches, but most people should try turning the brightness down before putting themselves into that category.
Newer monitors are bright AF.
My wife was able to buy a monitor with someone else's money, so I recommended she get the LG Ultrafine 5k. It's an amazing monitor, and way too bright at default settings. We both would get headaches from using it until we knocked the brightness down a notch or two.
yeah I also discovered that with my new monitor, it actually improved a bunch when I changed to backlight color from cold to warm, but it skews color correctness on it.
Every time I have tried adjusting a modern monitor for comfort, I've put the brightness setting the lowest value offered by the firmware and it's still too bright.
its not that someone does or does not have "special eyes" its a what are you optimizing for as always, because if you go look at the stats in a different direction using a cool colored backlight, light themes increase eyestrain and mess with your sleep cycles due to artificial blue light exposure, dark schemes reduce that. Light schemes are less power efficient on modern display panels so if you are optimizing for battery life guess what dark theme wins. Then when you get to "special eyes" there are a lot of people who have Myopia or Astigmatism, which dark themes can produce halation, chances are light themes are better for you there. If you are trying to present on a large screen having a theme that is somewhere in the middle, and a little darker for dark rooms and a little lighter for light rooms wins.
My point is more or less there is a ton of nuance here where saying "SEE SEE SEE SEE SEE SCIENCE PROVES MY PERSONAL PREFERENCES RIGHT" is wrong, and the author honestly skips over all of that to justify their own preferences for some reason.
"I'm right because science" is a tactic to insulate against criticism, it preemptively accuses you of "denying science" if you dare to disagree.