Minimizing your keyboard layout is a slippery slope. A few months ago, I built the Ferricy, a 34-key-split-ortho-ergo keyboard. The Ferricy is a fork of the Ferris Sweep MX Bling. The Ferricy, designed by icyphoxMy daily use consists of a bit of prose and a lot of program, my layout has evolved accordingly. Base Layer Colemak with no modsThe base layer contains alphabets, four symbols and four whitespace keys: Alphas: Stock Colemak, with no modifications whatsoever Symbols: . , / ; Whitespace...| oppiliappan's μblog
a static site {for, by, about} me| oppi.li
a static site {for, by, about} me| oppi.li
I use ssh a lot. Copying text from the remote machine to the host machine always sucked. But OSC-52 makes that easy. OSC-52 is an ANSI escape sequence to write text to the terminal emulator. The terminal emulator, if it understands what is going on, will in turn write this text to the system clipboard. What this means is some printf magic can send text to your clipboard. I store this one-liner in a script called oclip: printf"\033]52;c;%s\007""$(base64<&0)" and I run it with: remote $ cat som...| oppiliappan's μblog
tbsp (tree-based source-processing language) is an awk-like language that operates on tree-sitter syntax trees. To motivate the need for such a program, we could begin by writing a markdown-to-html converter using tbsp and tree-sitter-md. We need some markdown to begin with: # 1 heading content of first paragraph ## 1.1 heading content of nested paragraph For future reference, this markdown is parsed like so by tree-sitter-md (visualization generated by tree-viz): document | section | | atx_h...| oppiliappan's μblog
I regularly switch between exactly two things while working, a “current” and an “alternate” item; a lot of tools I use seem to support this flow. git Pass - to git-checkout to switch to the previously active branch: $ git branch* foobar$ git checkout bar$ git branchfoo* bar$ git checkout -$ git branch* foobar bash - cd This may not be exclusive to bash: ~/foo $ cd ~/bar~/bar $ cd -~/foo $ This is especially handy in combination with my git-worktree flow: ~/main-branch $ gwj feature~/f...| oppiliappan's μblog
I cobbled together a journaling system with {neo,}vim, coreutils and dateutils. This system is loosely based on Ryder Caroll’s Bullet Journal method. The format The journal for a given year is a directory: λ ls journal/2022/ 2023/ In each directory are 12 files, one for each month of the year, numbered like so: λ ls journal/2023/01 02 03 04 05 06 07 08 09 10 11 12 We can now begin writing stuff down: λ vim journal/2023/1 Every month must start with a calendar of course, fill that in with...| oppiliappan's μblog
I took interest in the Egyptian rendition of the afterlife recently. Parts of the Soul Ancient Egyptians believed that the soul comprised of several components: ren ka ib ba sheut Egyptians emphasized on preserving the different parts of the soul. Mummification for example, served to preserve the physical part of the soul. The other components have their respective preservation strategies. Of all of these bits, I find ren, which simply means name, to be the most interesting. Ba, the human-hea...| oppiliappan's μblog
Earlier this month, I decided that I would laugh at Indian customs in the face by building a split-ergo mechanical keyboard from scratch rather than purchasing a Moonlander. The finished productSourcing the parts If you, like me, live in India, you might find this section useful. My approach to finding parts: Check reputed, local online stores Check physical hardware stores Import the part PCBs This was by far the hardest component to procure. Fabrication services have certain capabilities. C...| oppiliappan's μblog
Tree-sitter queries allow you to search for patterns in syntax trees, much like a regex would, in text. Combine that with some Rust glue to write simple, custom linters. Tree-sitter syntax trees Here is a quick crash course on syntax trees generated by tree-sitter. Syntax trees produced by tree-sitter are represented by S-expressions. The generated S-expression for the following Rust code, fn main() {let x =2;} would be: (source_file (function_item name: (identifier) parameters: (parameters) ...| oppiliappan's μblog
Flakes are very handy to setup entirely pure, project-specific dependencies (not just dependencies, but build steps, shell environments and more) in a declarative way. Writing Flake expressions can get repetitive though, oftentimes, you’d much rather start off with a skeleton. Luckily, nix already supports templates! You might already be familiar with nix flake init, that drops a “default” flake expression into your current working directory. If you head over to the manpage: nix flake i...| oppiliappan's μblog
I have been working on an editor for the One Bit Image file format in Rust and SDL2. This entry in my blog follows my progress on the editor. The days are listed in reverse chronological order, begin from the bottom, if this is your first time on this page. Day 20 More lisp stuff! I added a new brush, for rectangular selections. While selection doesn’t do much on its own, the selected area can be passed onto a lisp procedure, for example, a procedure to draw horizontal black and white lines...| oppiliappan's μblog
Earlier this week, I began migrating my repositories from Github to cgit. If you care at all about big corporates turning open-source into a T-shirt farming service, this is the way to go. Offerings cgit is very bare bones. It is cgi-based web interface to git, and nothing more. You may browse repositories, view diffs, commit logs and even clone via http. If you are looking to replace Github with cgit, keep in mind that cgit does not handle issues or pull/merge requests. If people wish to con...| oppiliappan's μblog
I have been eyeing operating systems with functional package managers for a while now, aka, NixOS or Guix. Reproducible builds, declarative and rollback-able system configuration, system consistency, all sound pretty cool. I have been using NixOS for about a month now. Installation I went with their minimal installation ISO. The installation was pretty smooth from start to end, no hitches there. The entire manual is available offline, and is accessible during the installation. Very handy. Set...| oppiliappan's μblog
You’ve read a lot of posts about the shortcomings of the Go programming language, so what’s one more. Lack of sum types Type assertions Date and Time Statements over Expressions Erroring out on unused variables Error handling Lack of Sum types A “Sum” type is a data type that can hold one of many states at a given time, similar to how a boolean can hold a true or a false, not too different from an enum type in C. Go lacks enum types unfortunately, and you are forced to resort to craft...| oppiliappan's μblog
Rust’s type system is Turing complete: FizzBuzz with Rust Traits A Forth implementation with Rust Traits It is impossible to determine if a program written in a generally Turing complete system will ever stop. That is, it is impossible to write a program f that determines if a program g, where g is written in a Turing complete programming language, will ever halt. The Halting Problem is in fact, an undecidable problem. How is any of this relevant? Rust performs compile-time type inference. ...| oppiliappan's μblog
This post contains a gentle introduction to procedural macros in Rust and a guide to writing a procedural macro to curry Rust functions. The source code for the entire library can be found here. It is also available on crates.io. The following links might prove to be useful before getting started: Procedural Macros Currying Or you can pretend you read them, because I have included a primer here :) Contents Currying Procedural Macros Definitions Refinement The In-betweens 5.1 Dependen...| oppiliappan's μblog
I’ve always been an admirer of pixel art, because of it’s simplicity and it’s resemblance to bitmap font design. Recently, I decided to take the dive and make some art of my own. I used GIMP because I am fairly familiar with it. Aseprite seems to be the editor of choice for animated pixel art though. Setting up the canvas Picking a canvas size is daunting. Too small, and you won’t be able to fit in enough detail to make a legible piece. Too big and you’ve got too many pixels to work...| oppiliappan's μblog
Last weekend, I was tasked with refactoring the 96 unit tests on ruma-events to use strictly typed json objects using serde_json::json! instead of raw strings. It was rather painless thanks to vim :) Here’s a small sample of what had to be done (note the lines prefixed with the arrow): → useserde_json::{from_str};#[test]fn deserialize() {assert_eq!(→ from_str::<Action>(r#"{"set_tweak": "highlight"}"#),Action::SetTweak(Tweak::Highlight { value:true}) );} had to be converted to: → usese...| oppiliappan's μblog
I am not an expert with fonts, but I do have some experience 1, and common sense. This post aims to debunk some misconceptions about font sizes! 11 px on your display is probably not 11 px on my display. Let’s do some quick math. I have two displays, 1366x768 @ 21” and another with 1920x1080 @ 13”, call them A and B for now. Display A has 1,049,088 pixels. A pixel is a square, of side say, s cm. The total area covered by my 21” display is about 1,066 cm^2 (41x26). Thus, Display A Dime...| oppiliappan's μblog
I learnt about termux from a friend on IRC recently. It looked super gimmicky to me at first, but it eventually proved to be useful. Here’s what I use it for: rsync Ever since I degoogled my android device, syncing files between my phone and my PC has always been a pain. I’m looking at you MTP. But, with termux and sshd all set up, it’s as simple as: $ arp Address HWtype HWad ... 192.168.43.187 ether d0:0 ... $ rsync -avz 192.168.43.187:~/frogs ~/pics/frogs ssh & tmux My phone doubles a...| oppiliappan's μblog
My 4th semester involves ARM programming. And proprietary tooling (Keil C). But we don’t do that here. Building Assembling and linking ARM binaries on non-ARM architecture devices is fairly trivial. I went along with the GNU cross bare metal toolchain binutils, which provides arm-as and arm-ld (among a bunch of other utils that I don’t care about for now). Assemble .s files with: arm-none-eabi-as main.s -g -march=armv8.1-a -o main.out The -g flag generates extra debugging information that...| oppiliappan's μblog
This piece aims to highlight (pun intended) some of the reasons behind my color free editor setup. Imagine highlighting an entire book because all of it is important. That is exactly what (most) syntax highlighting does. It is difficult for the human eye to filter out noise in rainbow barf. Use color to draw attention, not diverge it. At the same time, a book devoid of color is boring! What is the takeaway from this 10 line paragraph? What are the technical terms used? Prose and code are cert...| oppiliappan's μblog
After going through a bunch of static site generators (pelican, hugo, vite), I decided to roll my own. If you are more of the ‘show me the code’ kinda guy, here you go. Text formatting I chose to write in markdown, and convert to html with lowdown. Directory structure I host my site on GitHub pages, so docs/ has to be the entry point. Markdown formatted posts go into posts/, get converted into html, and end up in docs/index.html, something like this: posts=$(ls-t ./posts)# chronological o...| oppiliappan's μblog
Decided to do one of these because everyone does one of these. My entire setup is managed with GNU stow, making it easier to replicate on fresh installations. You can find my configuration files on GitHub. I run Void Linux (glibc) on my HP Envy 13” (2018). To keep things simple, I run a raw X session with 2bwm as my window manager, along with dunst (notification daemon) and Sam’s compton (compositor) fork. I am a fan of GNU tools, so I use bash as my shell, and coreutils to manage files, ...| oppiliappan's μblog
I finally got around to installing Void GNU/Linux on my main computer. Rolling release, non-systemd, need I say more? As with all GNU/Linux distributions, wireless networks had me in a fix. If you can see this post, it means I’ve managed to get online. It turns out, wpa_supplicant was detecting the wrong interface by default (does it ever select the right one?). Let us fix that: $ sudo rm -r /var/service/wpa_supplicant $ sudo killall dhcpcd What is the right interface though? $ iw dev ... I...| oppiliappan's μblog
Glyph Bitmap Distribution Format is no more, as the creators of Pango, one of the most widely used text rendering libraries, announced their plans for Pango 1.44. Until recently, Pango used FreeType to draw fonts. They will be moving over to Harfbuzz, an evolution of FreeType. Why? In short, FreeType was hard to work with. It required complex logic, and provided no advantage over Harfbuzz (other than being able to fetch opentype metrics with ease). Upgrading to Pango v1.44 will break your GTK...| oppiliappan's μblog
Onivim is a ‘modern modal editor’, combining fancy interface and language features with vim-style modal editing. What’s wrong you ask? Apart from buggy syntax highlighting, broken scrolling and others, Onivim is proprietary software. It is licensed under a commercial end user agreement license, which prohibits redistribution in both object code and source code formats. Onivim’s core editor logic (bits that belong to vim), have been separated from the interface, into libvim. libvim is ...| oppiliappan's μblog
Bash is tricky, don’t let your editor get in your way. Here’s a couple of neat additions you could make to your vimrc for a better shell programming experience. Man pages inside vim Source this script to get started: runtime ftplugin/man.vim Now, you can open manpages inside vim with :Man! It adds nicer syntax highlighting and the ability to jump around with Ctrl-] and Ctrl-T. By default, the manpage is opened in a horizontal split, I prefer using a new tab: let g:ft_man_open_mode = 'tab'...| oppiliappan's μblog
Often times, when I run a vim command that makes “big” changes to a file (a macro or a :vimgrep command) I lose my original position and feel disoriented. Save position with winsaveview()! The winsaveview() command returns a Dictionary that contains information about the view of the current window. This includes the cursor line number, cursor coloumn, the top most line in the window and a couple of other values, none of which concern us. Before running our command (one that jumps around t...| oppiliappan's μblog
a static site {for, by, about} me| oppi.li
a static site {for, by, about} me| oppi.li
a static site {for, by, about} me| oppi.li