• On Linux, Neovim, CLI tools, and general productivity
  • Most are bite-sized articles which can be finished under 2 minutes

Distrobox is the greatest escape hatch for NixOS

TL;DR Use Distrobox when nixpkgs fails you or you don’t bother with declarative configuration. Introduction Never have I expected this much friction and frustration when switching to NixOS as my daily driver for development work. 1. Only nodejs 18 and above are available on nixpkgs I don’t get to choose what nodejs versions to use for work. For legacy projects I need nodejs 8, 14, 16 etc. The “oldest” compiled nodejs version available in nixpkgs is 18. I found Nix package versions but it requires compiling them from source. I can’t tell my boss “I’m compiling Nodejs 10 please wait 4 hours” before working on it. How I miss fnm. ...

March 31, 2025 · 3 min

How to Use nixCats-nvim in NixOS

flowchart TD A[Start] --> B{Is plugin in nixpkgs?} B -->|Yes| C[Add to optionalPlugins] B -->|No| D[Add to flake inputs] C --> E[Add any plugin dependencies and tools] D --> E E --> G[Register to lze in init.lua] G --> K[Run nix build .] K --> L[Test with ./result/bin/nvim] TL;DR Check it out: nixCats-nvim-example Run git clone https://github.com/kohane27/nixCats-nvim-example.git ~/.config/nixCats-nvim and start tinkering! Caveat My template assumes you are familiar with the Neovim plugin ecosystem, like adding plugins with lazy.nvim in a normal Linux/MacOS environment. This guide only shows you how to do so in Nix/NixOS. ...

March 29, 2025 · 5 min

Which one should I use: programs.neovim, nixCats-nvim, nixvim or nvf?

flowchart TD A[How do you use Neovim?] --> B[Basic text editing] A --> C[IDE/PDE experience] B --> D[Use programs.neovim] C --> E[Configuration preference?] E --> F["Nix manages plugins Lua configures nvim"] E --> G[Fully in Nix] F --> H[Use nixCats-nvim] G --> I["Use nvf"] H --> J[Starting point?] J --> K[Already using lazy.nvim] J --> L[Want maximum control] K --> M["templates/LazyVim"] L --> N["templates/example"] click C "https://www.youtube.com/watch?v=QMVIJhC9Veg" _blank click D "https://nixos.wiki/wiki/Neovim" _blank click H "https://github.com/BirdeeHub/nixCats-nvim" _blank click K "https://github.com/folke/lazy.nvim" _blank click I "https://github.com/NotAShelf/nvf" _blank click M "https://github.com/BirdeeHub/nixCats-nvim/tree/main/templates/LazyVim" _blank click N "https://github.com/BirdeeHub/nixCats-nvim/tree/main/templates/example" _blank programs.neovim If the following describes how you use neovim: ...

March 29, 2025 · 4 min

hop.nvim: 2-character bidirectional jump for the current line (like leap.nvim)

TL;DR Use hop.nvim for leap.nvim-like bidirectional jumps but only for the current line. Introduction The search is finally over. I can have leap.nvim-like jump for the current line. Little did I know, hop.nvim is the plugin that does exactly what I want. Features Bidirectional jump. It means that regardless of the cursor location, I can jump to anywhere in the current line (leap.nvim default). I no longer need to remember to use f to jump forward and F to jump backwards. 2-character. The labels appear only after 2-character search (same as leap.nvim) My hop.nvim Configuration return { "smoka7/hop.nvim", event = "VeryLazy", opts = { keys = "jklasdfghqwertyuiopzxcvbnm", create_hl_autocmd = false, dim_unmatched = false, teasing = false, }, config = function(_, opts) vim.api.nvim_set_hl(0, "HopNextKey", { fg = "#000000", bg = "#CCFF88", bold = true }) local hop = require("hop") local keymap = { ["f"] = function() hop.hint_char2({ current_line_only = true, jump_on_sole_occurrence = false, }) end, ["t"] = function() hop.hint_char2({ current_line_only = true, jump_on_sole_occurrence = false, hint_offset = -1, }) end, } local modes = { "n", "x", "o" } for key, func in pairs(keymap) do vim.keymap.set(modes, key, func, { remap = true }) end hop.setup(opts) end, } With the field keys, I can almost guarantee that I can reach wherever I want in the current line with f{2-char}j. ...

July 14, 2024 · 2 min

Step-by-Step Guide: Installing NixOS on VirtualBox for librephoenix's NixOS Config

TL;DR Download the Minimal ISO image and follow the Manual Installation to install librephoenix-nixos-config. I can’t stress this enough: DO NOT use any graphical ISO images like GNOME or Plasma Desktop! Use the Minimal ISO image not because we’re trying to be cool but because we want to make it work. Introduction If you think it’s as straightforward as installing Ubuntu, you’re in for a big surprise. There are so many gotchas along the way that I have to write it down for my future self, and hopefully for some other poor souls that stumble upon this article. ...

March 10, 2024 · 6 min

3 Ways to Use Reverse Split Tunneling for ProtonVPN on Linux

TL;DR Reverse split tunneling: ProtonVPN with WireGuard <– what I current use proton-privoxy <– what I used but broke one day forked protonvpn-cli-community Bonus: A dedicated app like browser/terminal routing through VPN: vopono Introduction I use ProtonVPN when connecting to api.openai.com. For all other traffic, I don’t want need a VPN. Turned out it’s a feature called reverse split tunneling. This feature is only available on Windows and Android (ref), and not supported for the official Linux CLI (ref). I’ll introduction 3 ways to do this as mentioned above. ...

October 23, 2023 · 4 min

The Definitive Guide To qmk Compiling And Flashing chocofi With Sea Picro (rp2040)

I recently bought a chocofi and it took me days to figure out how to compile and flash my keymaps to it. Introduction Spec chocofi: low profile 36 keys split keyboard Controller: Sea Picro (USB-C, RP2040, 16MB, Black - no display) This Flashing Controllers is a very good introduction. With our controller being Sea Picro, we can’t just use qmk commands such as qmk compile -kb chocofi -km default, because it compiles to a hex file. ...

September 9, 2023 · 3 min

kanata: qmk for Your Laptop Keyboard When Your qmk Keyboard is Not Around

TL;DR Use kanata when your qmk keyboard is not around. Introduction I have a qmk keyboard bought from keebio (note: highly recommend!): However, sometimes I’m on the go, and I’m forced to use my laptop keyboard. After being spoiled by qmk’s insane customizability, I couldn’t go back to a regular keyboard. I found kanata and kmonad and they could simulate most of my qmk experience. Why kanata over kmonad? The exact reason Why I built and use kanata. When using kmonad, I need to fully press the modifiers much longer for them to be registered. A slight tap is not registered. Like #466, “when I type capital F, 90% of times it comes out as lowercase f.” On the other hand, kanata doesn’t have this problem. ...

May 9, 2023 · 2 min

plocate: Not a Drop-in Replacement If You're Using btfrs

TL;DR If you want to use plocate while your filesystem is btrfs, do the following: edit /etc/updatedb.conf: replace PRUNE_BIND_MOUNTS = "yes" with PRUNE_BIND_MOUNTS = "no" save the file update the db with sudo updatedb test again with $ locate home to see any outputs from home directory Introduction plocate is supposed to be a much faster drop-in replacement for mlocate, but I had a lot of troble getting it to work. ...

May 9, 2023 · 1 min

Todoman+tasks+Nextcloud: Ditch Your Proprietary TODO apps like Todoist

TL;DR Stack: Nextcloud: server tasks: Android client Todoman: cli integration vdirsyncer: “database” Together they can sync across your Linux desktop and Android devices. Introduction Why switched away from Todoist? Proprietary No cli integration Notes The above solution does take some time to set it up. But afterwards, it’s set-and-forget. Also, check out my How to Migrate From OneDrive to Nextcloud to get started on Nextcloud. Tools Nextcloud: server that glues everything together tasks: Android client on the go Todoman: cli integration vdirsyncer: synchronizes TODOs between devices autovdirsyncer: monitors the TODO db and update accordingly and automatically Getting Started Install the packages pacman -Syu todoman vdirsyncer autovdirsyncer Notes The binary for todoman is todo. Install tasks on your Android device Tips ~/.config/vdirsyncer/config: [storage calendar_remote] type = "caldav" url = "https://efss.qloud.my/remote.php/caldav/" username.fetch = ["shell", "echo $NEXTCLOUD_USERNAME"] password.fetch = ["shell", "echo $NEXTCLOUD_PASSWORD"] I set NEXTCLOUD_USERNAME and NEXTCLOUD_USERNAME in /etc/environment so that autovdirsyncer can read the values when autovdirsyncer.service starts up. ...

May 9, 2023 · 1 min