

Good point! But I think lib.mkMerge only merges options in a module system like the ones used in NixOS, Home Manager, and flake-parts configs. In this situation I think the function to use would be lib.attrsets.recursiveUpdate
Just a basic programmer living in California


Good point! But I think lib.mkMerge only merges options in a module system like the ones used in NixOS, Home Manager, and flake-parts configs. In this situation I think the function to use would be lib.attrsets.recursiveUpdate


I think you can use import to load the expression from each file, and the // operator to combine imported attribute sets. Like this:
Edit: This doesn’t work - see replies
# flake.nix
{
inputs =
import ./inputs/nixpkgs.nix //
import ./inputs/nix-index.nix;
# ...
}
# inputs/nixpkgs.nix
{
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
}
# inputs/nix-index.nix
{
nix-index-database = {
url = "github:Mic92/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
}


I just rewatched TNG season 1, and I found it much more fun than I remembered! (Excluding Code of Honor ofc.) Super goofy, super Wesley-heavy. But fun!


Not OP, but I’ve been using Niri as my daily driver for almost two years (since v0.1.2). The stability and polish have really impressed me. In addition to the scrolling workflow it has some especially nice features for screen sharing & capturing, like key binds to quickly switch which window you are sharing, and customizable rules to block certain windows when showing your whole desktop.
I do use a 40" ultrawide. Looking for options for getting the most out of an ultrawide was how I got into scrolling window managers.
I only occasionally use my 13" laptop display. I still like scrolling because I like spatial navigation. Even if windows end up mostly or entirely off the screen I still think about my windows in terms of whether they’re left, right, up, or down from where I’m currently looking.
I don’t like traditional tiling as much because I find squishing every window to be fully in view to be awkward; and with e.g. i3-style wms if I want to stash a window out of view, like in a tab that’s a separate metaphor I have to keep track of, with another axis where windows might be. Scrolling consistently uses on spatial metaphor, placing all windows on one 2D plane with one coordinate system.


Home Manager is a Nix tool for managing configuration for a single user, usually on a Linux or MacOS system, or possibly WSL. You configure installed programs, program configuration (such as dot files), and a number of other things, and you get a reproducible environment that’s easy to apply to multiple machines, or to roll back configuration, etc. I find it helpful for having a clear record of how everything is set up. It’s the sort of thing that people sometimes use GNU Stow or Ansible for, but it’s much more powerful.
A Home Manager configuration is very similar to a NixOS configuration, except that NixOS configures the entire system instead of just configuring user level stuff. (The lines do blur in Nix because unlike traditional package managers where packages are installed at the system level, using Nix packages can be installed at the system, user, project, or shell session level.) Home Manager is often paired with NixOS. Or on Macs Home Manager is often paired with nix-darwin. As I mentioned, the Home Manager portion of my config is portable to OSes other than NixOS. In my case I’m sharing it in another Linux distro, but you can also use Home Manager to share configurations between Linux, MacOS, and WSL.


When I’m pairing with someone who uses VSCode it’s usually painful how slow they are about finding and opening files. And so much screen space is taken up by stuff that is not code. It’s extra frustrating because even VSCode has built-in solutions for all of this, but lots of people don’t seem to understand how to use it efficiently.


For work it’s Fedora + Home Manager because the remote admin software doesn’t support NixOS. Thankfully I’ve been able to define my dev environment almost fully in a Home Manager config that I can use at work and at home.
I use lots of Neovim plugins. Beyond the basic LSP and completion plugins, some of my indispensables are:


I was reading recently about how Tailscale makes peer-to-peer connections work, which I thought was quite interesting. If we stop using NAT there is still an issue of getting traffic through stateful firewalls. That can be hard without a server because, for example, in some cases you need to coordinate two nodes sending each other messages on the same port nearly simultaneously to get all the intervening firewalls to interpret that as an “outbound” session from both sides to allow traffic through. https://tailscale.com/blog/how-nat-traversal-works


My understanding is that the NixOS Lutris package runs with a virtual FHS that is built with a selection of libraries for running Wine. I think that might mean it doesn’t hook up libraries that are configured with nix-ld. If the game runs with steam-app, but not with Lutris, then it sounds like there’s a library missing from the Lutris FHS.
You can override to fix that. Looking at the game logs could give you information about which libraries are missing. Or you could add in everything that steam-app uses, the way you configured nix-ld.
There’s a configuration snippet that might point you in the right direction in this thread: https://discourse.nixos.org/t/nix-overlay-to-change-fhs-environment/54139/2


No, if something goes wrong with the VPN then the confined service will be unable to reach the internet. The setup runs the confined process in a network namespace that does not have a route to your default wifi or ethernet interfaces. If the VPN interface isn’t set up correctly, or stops working there is no other route out.
You can test this with or without setting up VPN-Confinement. To do a quick test without any VPN setup, create a test service like this:
systemd.services.test-unit = {
serviceConfig = {
NetworkNamespacePath = "/run/netns/test";
Type = "oneshot";
};
script = ''
${pkgs.iputils}/bin/ping 1.1.1.1
'';
};
Create a matching network namespace that doesn’t route anywhere:
sudo ip netns add test
Then set the unit running, and watch its output:
sudo systemctl start test-unit.service
journalctl -u test-unit.service -f
You’ll see ping report that the network is unreachable. If you delete the namespace while ping is running it will continue to report that the network is unreachable.
sudo ip netns del test
(If you don’t want to bother with a systemd unit, you can run a process in a given network namespace using sudo ip netns exec <namespace> <command>. For example, sudo ip netns exec test ping 1.1.1.1.)
If the namespace wasn’t set up for whatever reason the confined service won’t start. (See the edit on the post.)
I also did some tests with the VPN-Confinement setup with this test unit:
systemd.services.test-unit = {
serviceConfig = {
Type = "oneshot";
};
script = ''
while true; do
${pkgs.curl}/bin/curl https://am.i.mullvad.net/connected
sleep 5
done
'';
vpnConfinement = {
enable = true;
inherit vpnNamespace;
};
};
If I set vpnNamespace to a name that doesn’t match a configured vpnNamespace then the service won’t start.
If I bring down the VPN namespace while that curl loop is running with sudo systemctl stop wg.service then test-unit also stops, because of the systemd dependencies that systemd.services.<name>.vpnConfinement sets up.
If I bring down the network namespace manually while the curl loop is running with sudo ip netns del wg then the curl loop keeps running, and continues to report that it is connected to Mullvad. I guess the network namespace continues to exist while a running process is using it.
If I bring down the VPN network interface with sudo ip -n wg link set dev wg0 down then curl fails with status=6/NOTCONFIGURED


I use a chat interface as a research tool when there’s something I don’t know how to do, like write a relationship with custom conditions using sqlalchemy, or I want to clarify my understanding on something. first I do a Kagi search. If I don’t find what I’m looking for on Stack Overflow or library docs in a few minutes then I turn to the AI.
I don’t use autocompletion - I stick with LSP completions.
I do consider environmental damage. There are a few things I do to try to reduce damage:
On the third point, my understanding is that when you write a message in an LLM chat all previous messages in the thread are processed by the LLM again so it has context to respond to the new message. (It’s possible some providers are caching that context instead of replaying chat history, but I’m not counting on that.) My thinking is that by starting new threads I’m saving resources that would have been used replaying a long chat history.
I use Claude 4.5.
I ask general questions about how to do things. It’s most helpful with languages and libraries I don’t have a lot of experience with. I usually either check docs to verify what the LLM tells me, or verify by testing. Sometimes I ask for narrowly scoped code reviews, like “does this refactored function behave equivalently to the original” or “how could I rewrite this snippet to do this other thing” (with the relevant functions and types pasted into the chat).
My company also uses Code Rabbit AI for code reviews. It doesn’t replace human reviewers, and my employer doesn’t expect it to. But it is quite helpful, especially with languages and libraries that I don’t have a lot of experience with. But it probably consumes a lot more tokens than my chat thread research does.
For the r case I think you need to set the mapping in “operator pending” mode, which you get by putting "o" in the same position you already have "!".
I don’t know what the issue is with command mode.
There is plenty of precedent for custom escape bindings, often using jk or jj. You might be able to find examples to get an idea of the best way to set up those bindings.
There might be an issue with <C-space> in particular if it has existing mappings in certain modes. I know that auto-complete plugins often use that mapping to make the completions menu appear. There might be some interaction with that mapping specifically with plugins you’re using, or with built-in behavior. I suggest experimenting with a different mapping to narrow down whether problems are due to the way you are writing mappings, or to a specific interaction with that key sequence.


I haven’t used Forgejo, but from the docs it looks like it’s actions system is nearly identical to Github’s. And yes, that sounds like a good case for a scheduled workflow


Ah, space interns! Sounds a bit like Prodigy season 2.


My god what is even the point now?


I haven’t gotten much into flake-parts, but my understanding is that it creates a module system very similar to NixOS modules and Home Manager modules. Except that instead of defining a system configuration, flake-parts modules define flake outputs.
So I don’t think you would use it in your NixOS configuration. If your configuration uses a flake there might be use cases for using it at the flake level. For example your flake defines a nixosConfigurations output, which is a set with an attribute for each host. If you had some unusually complicated code in that flake output you might use flake-parts to modularize it.
Or I suppose flake-parts is largely aimed at simplifying per-system outputs like packages and devShells. Once again, if you wanted to split those definitions over multiple files flake-parts can do that. Or you can use it just to get flake-parts’ eachDefaultSystem helper if you don’t want to use equivalent functionality from flake-utils, or the built-in genAttrs function.
Although I love the NixOS module system, I haven’t used flake-parts because I haven’t had a case where I want reusable modules in the context of flake outputs. Usually my flakes are a pretty uncomplicated combination of genAttrs, basic devShells, basic overlays, and package expressions that I build with callPackage.


I like using leap.nvim for this since it has an added feature where you can select the node you want in one step by typing a two-letter label.
There is a similar feature in flash.nvim.


Of course I did the troll voice!


The first season, and the first few episodes of season two take some extra weird turns because of the revolving door of producers during that period. The original producer left the show during season one. Then a duo took over who took the story in quite a different direction. Those two left in early season two. After that production finally settled into a more stable state.
Anyway the characters and acting are great, and that counts for a lot!
Whoops! Guess I was wrong. After some experimenting it looks like the flake system parses, but does not evaluate
flake.nixto read inputs. I also experimented with string concatenation, and that failed with the same error:A “thunk” is an expression whose evaluation has been delayed. It’s a key piece of lazy evaluation. Remember that every expression in Nix is lazily evaluated.
It looks only literal attribute set, string, and path expressions will work in
inputs. I think that means it is not possible to split inputs over multiple files.