My Productivity Toolbox
27. December 2024
As an undergrad Electrical Engineering student I spend most of my time reading (web browsing + PDF textbooks), making technical notes, solving problem sets and occasional scientific / low-level programming. I hope to encourage some readers to make more conscious decisions regarding the tools they use, invest more time into optimizing their workflow and inspire people towards choosing free software more often.
Free Software is computer software distributed under terms that allow users to run the software for any purpose as well as to study, change, and distribute it ... it is a matter of liberty, not price
What's the point?
Even if your line of work differs significantly from mine, I urge you to read the following section as it's applicable to all facets of life.
It's easy to dismiss these ideas as unnecessary, overly-pedantic and a waste of time - I certainly had the same opinion in the past. However, if you spend just a few minutes considering potential improvements in your workflow, the initial time investment -> time potentially saved alone is often enough to make the improvement a very sensible idea. Furthermore, life has a tendency to keep getting busier the more one grows as a human being; the right time to make an improvement will rarely arrive, its a matter of now or never.
We often become obsessed with whatever we're currently working on and forget that there is indeed a long future ahead, in which you'd be very grateful that you took your foot off the throttle for a few moments and made that improvement, however insignificant it may seem:
The remarkable thing is, one does not only save time after making an improvement, it also serves as a learning experience. Let's imagine the cavemen instead decided to switch from square to circular wheels:
- They learned how to replace wheels and will be back on the road in no time if the wheels break. One of them discovered a new passion and now replaces wheels for all of his cavemen friends.
- They got a quick dopamine boost + sense of achievement and now pull the box of rocks with more energy than ever before.
- It made pulling boxes of rocks a whole new experience, something they itch to get started with every morning for days to come.
A win-win opportunity!
Guiding Principles
I base my tool choices on the following principles in order of importance:
- Data Ownership - Ensuring that my tools give me full control over my data and the work I produce, using standard, non-proprietary file formats. I aim to avoid vendor lock-in, have the option to self-host whenever possible and avoid relying on anyone else's infrastructure.
- Free and Sustainable Software - Prioritize using free and open-source tools that have long-term sustainability, are supported by a sizable community, and offer a rich ecosystem. This ensures the software wonβt disappear or become obsolete for many years to come. Bonus points if its written using a language I am proficient in, allowing me to understand what exactly is running on my computer and contribute to its development if needed. While these tools may come with a steeper learning curve, they align with my values and I see that as a worthy investment of time.
- Efficient - I favor tools that are lightweight, fast, and accessible directly from the terminal, avoiding unnecessary graphical interfaces. They should also be customizable enough to integrate seamlessly into my workflow, with every action at most a few keystrokes away. Reducing the energy wasted to achieve something is one of the keys to ensure more gets done.
- Keyboard-Centric and Ergonomic - Reducing mouse / pointer usage to a bare minimum allows one to keep their hands on the keyboard, a far more precise and efficient input device. The vast majority of interaction we have with computers is discrete - there is a single, undisputed aim (for example switching to a specific workspace) for any action we perform and having all 10 fingers available to communicate that aim to the computer is the obvious winner for discrete tasks. Of course, there are many situations where continuous input devices remain the appropriate choice, for example when drawing, one needs constant feedback about the stroke of a stylus, but that is rarely the case in my work and I have reached a point where nearly everything is possible without reaching for a mouse. With hopefully a lifetime of typing ahead, it's important to prevent RSI and ensure comfort by using software with sensible keybindings. The goal is to enjoy the typing experience and avoid frustrating contortions away from the home row, making the process of working something I look forward to doing.
- Minimal - I do my best work whilst in deep focus, working on a single task at a time. Although I try my best to give my full attention to the task at hand, eliminating potential distractions like notifications, strange AI assistants, unsolicited updates etc. is not only good for one's productivity, but also reduces the resources needed to run the software + risk of potential bugs. The suckless philosophy is one I fully agree with.
Something I have noticed is that tools either align with most / all of these principles (think Vim) or none of them (Microsoft's Word). It's reassuring that most people in the free software community have the same motives in mind and that these tend to be widely agreed upon views.
With that said, here's a deep dive into my current toolbox...
OS / Desktop Environment
I first encountered GNU/Linux as a young teen, trying to get something hosted on an AWS Free Tier EC2 instance. I thought it was something only used in servers, occasionally following Digital Ocean tutorials on how to get NGINX and Let's Encrypt working for me and my friends' latest website. It wasn't until I started taking programming seriously that I got familiar with Bash, first of all running Linux under WSL for tools like Docker and then switching to it as my main desktop operating system in 2023.
Now I can confidently say, Linux is an obvious choice for anyone who values Free Software, not just programmers or privacy enthusiasts. I hope to write about Linux for the layman soon, so I'll focus on it as something that can improve productivity for now.
Debian
Currently, Debian Testing (codename "Trixie" at the time of writing this) is my distribution of choice. I initially chose Debian after consulting my good friend and mentor 21a1ss3, who advised it as a less bloated alternative to the ubiquitous Ubuntu. After several issues with outdated Nvidia proprietary drivers, switching to the surprisingly stable testing branch has been a pleasant balance between rolling updates and making use of the abundant Debian-based-distro community support threads. Furthermore, Debian remains the de-facto distribution of choice for non-enterprise servers (including my home server currently), something becoming less relevant since the dawn of containerization but nonetheless useful.
Recently, I have been looking into NixOS, who's declarative nature, reproducibility and unification of dependency management through the Nix ecosystem make it a very attractive distribution. I plan to ascend its steep learning curve soon as I learn more about systems programming and look forward to switching to it, hopefully as my endgame OS.
Sway
Like many beginner Linux users, I initially used GNOME as my desktop environment, which I think remains a very suitable choice for the average user. After spending more and more time in the terminal, I discovered tiling window managers, the pinnacle of customizability and efficiency, and spent several months on the fence about the idea, using TMUX to avoid making the scary leap. Although I no longer use TMUX for desktop use, its session-persistence certainly remains a valuable tool when SSHing into a server.
For the uninitiated, a desktop environment (for example GNOME) refers to a collection of software to make a system suitable for daily personal computing needs. It includes not only a window manager, but also a variety of pre-installed apps (settings, notification manager, taskbar, lockscreen and much more). Starting with only a window manager on top of the base OS means one can customize many other parts of the system as they seem fit although it can certainly be a long and tricky process that the average user likely has little interest in doing. Tiling window managers in particular allow users to create, navigate and move application windows through workspaces completely using configurable keybindings, which are arranged as non-overlapping tiles by default, although stacking and "floating" (think default Windows / macOS window behaviour) windows are possible too. This keyboard-centric window management system reduces mental-overhead and can be shaped to fit your workflow and form routines - for example automatically launching applications in their usual workspaces on startup: exec swaymsg 'workspace 1; exec firefox'
The more choices we are forced to make, the more the quality of our decisions deteriorates.
I decided to choose a Wayland tiling window manager (Sway) as Wayland has been widely recognized as the future of Linux compositing and the vast majority of applications support it natively by now (Xwayland is available for older / buggy apps). Sway is more minimal than the other major Wayland WM, Hyprland, and its backwards compatibility with i3 (an extremely popular and older X-based WM) configuration files has proven to be very useful when it comes to configuring Sway. Here's some examples of things I had to install and configure that you might expect a desktop environment to include, so you can get an idea of what configuring a tiling window manager actually involves:
- sway-bar - Status / taskbar which can either output the output of a periodically executed shell script or be managed through an asynchronous JSON-based protocol to display the usual information such as time, battery percentage and network status.
- swaylock - Lock screen, can be configured to lock after a certain time period / closing a laptop's lid.
- bemenu - Application launcher, essentially just an interface for choosing from a list of strings (usually the contents of your
PATH
) which one can then execute to launch the application. Alternatively, compgen can be used to include aliases etc. which are not included inPATH
. - network-manager - TUI for managing WiFi networks.
- Mako - Minimal notification manager.
- grimshot - Unified screenshot utility.
- imv - Terminal image viewer.
Sway and most of the applications mentioned above are delightfully customizable, providing settings for all kinds of keybindings, colors and seamless integration with shell scripts, allowing you to mold its functionality to fit your workflow.
Here is a screenshot of what my desktop environment currently looks like:
PS you can make windows invisible for cool screenshots using swaymsg opacity set 0
DE: GNOME
in the neofetch output is an ironic example of one of many common issues when running a Wayland tiling window managers in 2024. That in particular is due to the XDG_CURRENT_DESKTOP=GNOME
env variable, which is a workaround to fix secrets decryption in electron apps. Unfortunately, such workarounds are littered throughout my dotfiles, however I must say, once you have patched sway for your daily usage and customized it to your liking, you can enjoy some snappy, distraction-free productivity. If you're someone who sticks to the basic browser / terminal-based apps most of the time and doesn't mind going on occasional tangents when installing new software, I can wholeheartedly recommend them. Furthermore, it's a good deterrent to avoid gaming π although I'm sure that is possible too with enough effort.
I can recommend the following resources when it comes to configuring a Sway system:
- Sway wiki
- Sway Subreddit wiki
- Blogs / other people's dotfiles
- Anything related to i3
Dotfile Management
It's important to enjoy an identical desktop experience, whether you're on your PC at home or using your laptop on the go. Even more important is backing it up in case your drive fails or you want to setup a new device. Application configuration files are usually found in the HOME directory and are known as ".dotfiles" due to their naming convention (.bashrc
, .gitconfig
etc.).
There are many possible approaches to managing such files but I believe having to learn a new tool for something so fundamental is unnecessary. Luckily, git
, which me and many readers surely use on a daily basis, is perfect for this. This article describes an approach which originally appeared on Hacker News and involves creating a "bare" repository in a dedicated folder, allowing you to add files in HOME
using an alias that doesn't conflict with any other repositories in the same directory.
I currently use GitHub as my remote git server, however I am considering self-hosting a git server + CI (probably using Gitea) in the near future.
Replicating your desktop environment on a new device simply involves cloning the dotfile repository as a bare repository as detailed in the article, checking it out into HOME
and then using the aliased command to add, commit and push config files in case of changes - this process can be done in a matter of minutes.
When it comes to packages, I simply keep a long list of names (or sometimes instructions for adding their apt source + integrity checks) as setting up new systems is not something I do very often, however it could easily be automated with a shell script. With NixOS, things would be even easier as every package installed on the system is kept track of in the config files.
Vi(m)
Vim is not just an editor, it's a way of life
The legendary terminal-based text editor vi
was released in 1976 (almost 50 years ago!) and is pre-installed on every UNIX system (a specification which GNU/Linux, macOS and several other operating systems comply with). It is a modal text editor based on the concept of motions, I won't go into detail on exactly how it works as there are already countless resources on the topic, but here's a brief overview:
- NORMAL mode - The editor starts in this mode and it is used for moving the cursor, navigating around the buffer (text currently being edited) and manipulating text using semantic sequences of commands, the so-called Vi(m) motions, for example
d2w
, which as the name suggestsd
eletes2
wow
ords. This is also where one executes editor commands such as:w
to write changes to the disk. - INSERT mode - One can switch to this from NORMAL mode by pressing
i
or commands likeA
, which executes a motion followed by entering INSERT mode (INSERT at the end of the current line). PressESC
to switch to back to normal mode and move the cursor. - VISUAL (BLOCK) mode - Vi equivalent to selecting text, particularly useful with so-called "text-objects", allowing users to
cib
-c
ut the texti
n theb
rackets. Multi-cursor editing is also possible.
You may wonder why a separate mode just for navigating the cursor makes sense. To answer that I urge you to consciously think about which keys you press the next time you're programming / editing a larger text. You should notice some very repetitive arrow key usage, constantly reaching for the mouse or perhaps some awkward "chorded" keyboard shortcuts, like those available in many conventional IDEs. This is slow and unergonomic, especially when programming, and although one can argue that the majority of time is spent thinking anyway, why slow down the thoughts once they start flowing?
Here's a slightly unrealistic but nonetheless impressive example of high-speed text-editing in vim:
If you're only going to take one thing from this post, learning vim motions (the NORMAL mode commands) in particular is the skill I'd recommend most (provided you can already touch-type at a reasonable speed). They have become a sort of lingua franca for navigating text and you can utilize take them everywhere, with countless applications and IDEs (for example VSCode) offering to some kind of implementation. There's even a game called VimGolf, where users compete to edit text using the least possible keystrokes. My favorite implementations in particular are:
- ZSH Shell's native Vim mode brings motions to the command prompt
- Zathura document viewer is very lightweight, configurable and allows moving around PDFs using Vim's familiar
hjkl
. - The browser extension Vimium which offers intuitive Vim-inspired keyboard shortcuts for navigating pages, opening links and much more. This one is a total game changer considering how much time one spends in the browser! Vimium's "open link" functionality in action:
However I must briefly point out that sometimes Vi(m) motions are truly unnecessary, for example bemenu (the Wayland application launcher I use) offers a Vim mode but I found it cumbersome to use modes for such short strings and have it disabled. That's not to say that they aren't addictive π - it can be very frustrating to have to use some software without any motion support (MongoDB Compass comes to mind), but luckily this tends to only be a problem with proprietary / emerging projects.
Here are my tips for learning Vi(m) motions:
- Recognize patterns ASAP - The motions are mostly consistent in design and you'll quickly be able to pick up patterns, for example that uppercase motions usually imply that the command applies from the cursor to the end of the line, and the various semantic meanings behind command letters.
- Learn by doing - Like with languages, after you have learnt the basics using a tutorial like the
:Tutor
command in Vim / Neovim, advanced topics are best discovered on the go, rather than reading the documentation from start to finish. - Switch back to NORMAL mode often - Unfortunately the
ESC
key is in an uncomfortable position on conventional keyboards, this is due to its position on the terminal Bill Joy was using when he originally wrote vi. However, moving the cursor using motions in NORMAL mode is the whole point of Vi(m) so try your best to forget about the existence of the arrow keys. Many people remapESC
to the useless Caps-Lock key, although in my opinion the best long-term solution is to switch to a programmable split keyboard and set it as one of the thumb buttons.
An interesting editor to keep an eye on is Kakoune, which aims to eliminate some of the inconsistencies / inefficiencies of Vim's motions. On paper, its philosophy makes more sense and its motions are indisputably better. Alas, its community is still rather small compared to Vim / Neovim, which is a huge disadvantage considering such terminal based editors need a lot of configuration and additional plugins to get the basic features one would find in a fully-fledged IDE working.
Neovim
Although there's nothing wrong with simply using Vim motions in your text editor of choice (I did this when first learning motions to make sure my productivity didn't flatline), using one of Vi's derivatives in the terminal provides clear advantages. Vi IMproved, also known as Vim, was written by Bram Moolenaar (who sadly passed away in 2023) in the early 90s and introduced many features necessary for it to remain competitive with other emerging IDEs of the time:
The most impactful feature of Vim was the introduction of Vimscript, a scripting language used for configuring the editor which gave rise to a plugin ecosystem and making the possibilities for configuration endless. However, as one can expect from something written over 30 years ago, the code base has been criticized for being messy, out-of-date, and having to learn a specialized scripting language just for configuring your editor is certainly not on everyone's To-Do list. Furthermore, Moolenaar's death sparked worries about its future maintenance.
Neovim is a modernized Vim fork with many committed maintainers and a flourishing plugin ecosystem, which is built around Lua (a simple scripting language popular in game development) for its configuration. I use Neovim as my primary text-editor for the following reasons:
- Lightweight, minimal and resource-friendly terminal app that starts up in a fraction of a second and handles large codebases without issues.
- Includes all base features available in Vi(m) and therefore also on 99% of servers you will ever work on.
- The configuration possibilities are limitless and there is a thriving community writing plugins for modern languages and even tools like Github's Copilot.
I want to stress that you should NOT feel rushed to switch straight to Neovim! I highly recommend mastering the motions in a text-editor you're already familiar with first and gradually building a config in your spare time, only switching once you feel ready. Versions of the text editor may come and go over the years but the motions have stayed the same for 50 years and unfortunately for Kakoune are unlikely to ever change - just look at the qwerty keyboard layout, which was designed for typewriters, is objectively worse than alternatives yet remains in use more than 150 years later...
Configuring Neovim
Although some programmers prefer using the default Neovim configuration (just like you'd find it on a brand new Debian installation), most people are going to have a hard time without the autocompletion, syntax highlighting and code suggestions expected in modern IDEs. Luckily these features can be added to Neovim by setting up a Language Server Protocol (LSP) client, installing the necessary LSP servers for your languages and Tree-sitter, a library that turns code into ASTs that other plugins can query and manipulate. Creating your first Neovim config can be an intimidating process, I recommend the following steps:
- Learn the basic syntax of Lua - This will make the rest of the process far easier. Luckily if you already have programming experience you can get this done in a couple of hours.
- Discover the built-in features - Vim / Neovim already have an abundance of handy features built in, for example a spell-checker and window-splitting / tabbing functionality. Finding these in the documentation and trying them out is important; they are often sufficient and you can avoid wasting time and resources installing extra plugins for some purpose you are already satisfied with. I personally prefer
:Lexplore
's lightweight nature much more than some of the file explorer plugins people recommend as "Must have Neovim extensions for beginners!". - Explore existing configurations - There are many so-called "Neovim distros" which have varying philosophies, for example LunarVim which tries to clone VSCode's functionality. However I wouldn't recommend starting with them, as they are often full of features you may never actually use (wasn't the whole point of switching to Neovim to get rid of those?) and one doesn't build an understanding of how the config works / how to fix potential issues. Instead I recommend taking more time to build a configuration from the ground up, perhaps starting with kickstart.nvim, a minimal starter config, which is written in a pedagogical style with comments explaining what every component does. After you have understood how it works, you can of course remove some of the features you don't see yourself needing and you'll have built the understanding to expand it with tools needed in your workflow (for example installing additional LSP servers through mason in the
servers
list). Furthermore, most people include their Neovim configs in their dotfiles (here's mine) which is a great way to draw inspiration.
The components which are truly essential in my opinion (and included in kickstart.nvim) are:
- lazy.nvim - a plugin manager, similar purpose to a package manager like
npm
- nvim-treesitter - provides syntax highlighting and a requirement for many other plugins
- nvim-lspconfig + mason - covers the LSP side of things
Note-taking
My note-taking setup is inspired by the following amazing articles:
Many people swear by note-taking "systems" (for example Obsidian), with features such as linking between notes and creating mindmaps. Although using such software offers a low barrier of entry, I'm unconvinced about their sustainability compared to using your own tailor-made text-editor and simple directory structure that has stood the test of time. For quick ideas and plans, I stick to regular .txt files, however there are indeed times when inserting maths, images and styling text is necessary, which so far Typst achieves delightfully. I have been using it for all of my university notes so far.
Typst
Typst is "a markup-based typesetting system ... designed to be an alternative to advanced tools like LaTeX". It was created in 2019 by two students from TU Berlin and despite its young age, it has proven to be a successful typesetting language with a fantastic standard library, an ultra-fast compiler written in rust (WASM compatible!) and a very concise syntax similar to markdown.
Reader's familiar with LaTeX's extremely verbose syntax will agree that Typst's is far simpler, which lets me focus on what I'm writing rather than how to write it - I've had no problems noting maths equations during lectures in real-time without any additional macros like Mr Castel described in his blog (although I've come to learn this is something best done whilst reviewing the content before / after the lecture).
That's not to say that it's less powerful. Formatting is controlled using a fully fledged scripting language very similar to JS and there is a prosperous set of templates and packages for things like drawing graphs. Some shortcomings are to be expected as it is so much newer than the LaTeX's mature ecosystem; I am particularly looking forward to HTML output which should be added to the compiler in the next major update.
Here's a picture of my note-taking setup:
The window on the right is Zathura, which has the output PDF open. To open the corresponding PDF for the file I'm currently working on, I added the following keybinding in my Neovim config:
vim.keymap.set("n", "<leader>z", ":silent !zathura --fork %:r.pdf<CR>")
I have found the Tinymist language service (available on mason) to work well, which provides an integrated formatter, compile-on-save and an LSP, for which I use the following settings:
tinymist = {
single_file_support = true,
settings = {
exportPdf = "onSave",
formatterMode = "typstyle",
},
}
I added the following rule to nvim-autopairs to autocomplete the dollar signs surrounding maths in Typst:
npairs.add_rule(Rule("$", "$", { "typst" }):with_pair(cond.not_after_regex("[a-z]", -1)))
Lastly, I recommend the img-clip.nvim extension which automates the process of saving an image from the clipboard in the correct place and then linking to it inTypst:
{
"HakonHarnes/img-clip.nvim",
event = "VeryLazy",
opts = {
default = {
dir_path = "images",
},
filetypes = {
typst = {
template = [[
#figure(
image("$FILE_PATH", width: 60%),
) <fig-$LABEL>
]],
},
},
},
keys = {
-- suggested keymap
{ "<leader>p", "<cmd>PasteImage<cr>", desc = "Paste image from system clipboard" },
},
},
Synchronization
For syncing my notes between devices I use git repositories as you may have guessed. Typst's source files behave well in diffs (unlike .doc and similar encoded file formats) and making changes through commits with short messages describing the contents has proven to be very useful.
I also include the compiled PDFs in the repositories and use GitHub pages to serve them statically, which makes opening notes on my phone / friends' devices quick and easy. I am planning to add Typst compilation in CI / CD to ensure the PDFs are always up-to-date in case changes are made to source from some device without a compiler installed.
Other Useful Apps
- Xournal++ - I use this handwriting app daily for solving university exercises and understanding difficult concepts. Although Neovim feels like an extension to my body at this point, something about writing with a stylus in hand feel more natural and allows me to really focus on the concept before typing it neatly with words and equations in Typst.
- More to come!
Peripherals
I will keep this section brief as I plan on making a very detailed post in the near future about keyboard layouts, their benefits and a custom split keyboard I am working on (and maybe replacing my laptop's built-in keyboard too!).
Here's a picture of my portable setup:
The keyboard is certainly the most important input device for my keyboard-centric system and I'm currently using the ZSA Voyager, a programmable, portable split keyboard with excellent build quality. Many thanks to my former colleague Bennet Gallein who's Moonlander initially inspired me to get into split keyboards. I'm using a qwerty layout based on the default GergoPlex layout, which means I mostly stick to the lower 40 keys of the Voyager - this is with the goal of preserving Vim motions' semantic nature without having to add a bunch of remappings to my Neovim config, although I may consider switching in the future.
The more efficient keyboard layouts such as Colemak and Dvorak certainly offer ergonomics improvements but typing speed stays mostly the same, and although qwerty is indeed an awful layout, it has become so deeply ingrained into society that I'm unsure if changing to something else is practical.
I'm currently using the XP-Pen Deco 02 drawing tablet, featuring a scroll-wheel, 6 buttons and a side button + eraser on the stylus. The official configuration software didn't play well with Wayland so I used input-remapper to program these inputs, with 4 of the buttons used for swtiching between Sway workspaces, Ctrl+Z, area screenshot and the scroll-wheel for ... scrolling. As for the stylus, I set the side button to right-click (although this is a little buggy), meaning it can do anything a mouse can do and has replaced my mouse / trackpad usage completely.
Thank you very much for reading! I hope this post helped you discover some cool tech and maybe even inspired you to make some changes in your daily workflow. I'd love to hear about any cool suggestions and am always happy to answer questions so don't hesitate to reach out!