Car'Log[n]

Being Cool, Fast, and Productive on Windows (SWE Workflow)

I have to admit, I'm still using Windows as my daily driver. Why? Well, I'm too lazy to install Ubuntu (or Arch, same thing) -- Also, I play games, so Windows is a must. Most commercial laptops and PCs come with Windows pre-installed, and it's a hassle to reinstall everything just for the sake of SWE culture. So, instead of figuring out how can I install a Linux as my daily driver, I did the opposite: I set out to make the Windows experience better for programming.

TLDR: It's a combination of pseudo-tiling-manager (built into Windows), some AutoHotKey scripts, old software from 2010 and 2015, WSL, Neovim and TMUX Before dive into the rest of this blog, I recommend watching this boomer guy's video on how he set up his developer workflow in Linux. Most of my ideas come from this video: My Developer Workflow - How I use i3, tmux, and vim, so credit where credit's due!

Pseudo-Tiling Manager

windows native virtual desktop, cool built-in feature

If you press <WIN-TAB>, it shows the "dashboard" of the desktop you're on. Try hitting <WIN-C-D> - it'll create a new (virtual) desktop. With this, we can use each desktop as a dedicated space for different applications that we use day-to-day. I share the same philosophy as ThePrimeagen: "I dislike tiling on one desktop, but I do like jumping around to each app like a StarCraft player". All we need is a good way to move between desktops because the original keybind was... let's say awful (it's <WIN-C-(arrow)>).

Like any other problem, someone has probably already solved it. In this case, windows-desktop-switcher comes to the rescue. I won't go into the details of how to install this software (just follow the readme, and you're good).

jumping_between_desktop

With this, we have better navigation keybinds: <CAPS-(123456789)> to move to each corresponding desktop and <CAPS-(qwertyuio)> to move each app to other desktop. One nice thing you can add is to automatically create all nine (virtual) desktops with a simple script like this:

createInitialDesktops(NumInitialDesktops)
{
    global DesktopCount, CurrentDesktop

    OutputDebug, Creating %NumInitialDesktops% initial desktops

    Current := CurrentDesktop

    Loop, % NumInitialDesktops - DesktopCount
    {
        createVirtualDesktop()
    }

    OutputDebug, Switching back to desktop %Current%
    _switchDesktopToTarget(Current)
}

createInitialDesktops(9)

You can also set it up to run on boot, so you can use these virtual desktops right from startup. Here's how to set it up to run on boot.

Old Software That Saves Me

The second thing that annoys me is the fact that I need to move my hand to use arrow keys. It's worsened by the fact that I use a 60% keyboard, and my arrow keys are on the second layer of the alt, menu, ctrl, / keys. I need to press the fn key each time I want to use my arrow keys. So, my thought was, "I need to change the button to activate the second layer, and I need to remap the arrow keys to the home row."

Enter TouchCursor, a 2010 software (that still works on Windows 11) that creates a second layer keyboard just by holding the <space> button. So instead of using arrow keys, I can use <space-(ijkl)> to navigate, <space-u> and <space-o> as <home> and <end>, and other cool stuff. You can customize it, but I suggest using <space-(hjkl)> instead of the default if you're planning to use Neovim as your editor. Trust me, your fingers will thank you later.

touch_cursor_remap

Another thing that grinds my gears is the fact that I can't use <M-tab> (that's alt+tab for you non-vim users) to move around different apps on different desktops. Yeah, most of the time I remember which app is on which desktop, but sometimes there's an I-rarely-use-app that I've put on desktop 5 -- 8. I needed some kind of fuzzy finder to locate apps currently open on my desktop, and that's where Switcheroo come in to save the day. Not only does it allow me to fuzzy find a tab, but it works on a global level for tabs/apps (unlike the Windows <M-tab> which is just works on desktop-level). Here's a screenshot of Switcheroo in action:

switcheroo

The (Kinda) Cool Part: WSL, Dotfiles, Neovim, and TMUX

Unless you're a game programmer, there's no way you'll code in the inferior OS environment that is Windows. All my coding shenanigans happen on WSL (Ubuntu). I use the built-in windows terminal, with some custom configuration, like a catgirl wallpaper and the Kanagawa theme. I've also set up the Ubuntu terminal as the default terminal. I love the idea of using the open-source alternative Wezterm (because the config is in Lua, just like Neovim), but none of those fancy features are needed right now for me. Maybe in the future when I decide to procrastinate by over-engineering my setup even more :D.

her_name_is_amatsuka_uto

For my code editor, I use Neovim (btw) because I was brainwashed by ThePrimeagen. Like a true chad, I didn't start with embedded Vim in VSCode or IntelliJ. I dove headfirst into Neovim (removing your electron editor helps/forces you to understand Neovim). Neovim has made my development experience nicer, partly because of muscle memory and partly because I learn new things every day, mostly from typing :h each time I need to know something. I've been using Neovim for the past 6 months, and I have no regrets. I could talk about Neovim all day here, but I'll create separate posts on how I set up my Neovim for different scenarios.

If you want to start your Neovim journey, try to understand basic Vim movements with this Vim Fundamentals course, or this wonderful docs. And if you're ready to start ricing your Neovim (because who doesn't love spending hours tweaking their editor?), try to understand kickstart.nvim. You can also check out my Neovim config here (if you're curious, or just want to judge my life choices): super-cool-nvim-config

One thing that's a must is accessibility to manage your dev settings. You don't need to remember the exact command to install zsh, or Python, or Zig, or Rust. You just need to write it once as a script and organize it. For this, I use GitHub to store my dotfiles, which have a tasks directory that stores the scripts to install everything I need to be productive. I store it as a bash script because it's still a tiny thing ( I don't install a lot of deps ). With this, I just need to clone my dotfiles and run ./run.sh to install and configure everything I need. Fun fact: most of them are actually webi installers. Good tools, check them out if you want to make life easier.

Next, If you don't know Tmux (terminal multiplexer), it's basically a tool that allows you to have multiple terminal sessions. The details of how it does it and why can be checked out in this course yes, it's another ThePrimeagen course . With this power, you can host every project in different terminals, persist their sessions, and jump around each project with a simple script like this (thanks again to ThePrimeagen, my personal productivity guru):

#!/usr/bin/env bash

if [[ $# -eq 1 ]]; then
    selected=$1
else
    selected=$(find ~/personal ~/work ~/.config ~/.local ~/dotfiles/.config ~/dotfiles/ ~/learn  -mindepth 1 -maxdepth 1 -type d | fzf)
fi

if [[ -z $selected ]]; then
    exit 0
fi

selected_name=$(basename "$selected" | tr . _)
tmux_running=$(pgrep tmux)

if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then
    tmux new-session -s $selected_name -c $selected
    exit 0
fi

if ! tmux has-session -t=$selected_name 2> /dev/null; then
    tmux new-session -ds $selected_name -c $selected
fi

if [[ -z $TMUX ]]; then
    tmux attach -t $selected_name
else
    tmux switch-client -t $selected_name
fi

TLDR: This script creates a new tmux session for each project if it doesn't already exist, or jumps to the existing tmux session if it does. When I execute the command with <C-f>, which is bound to this script, it opens a fuzzy finder on the personal, .config, .local, learn, and dotfiles directories, displaying a list of directories (projects) to select from.

jumping_tmux

This is how you can transform your Windows environment from an uncool developer environment to one that is on par with the Primeagen developer workflow (I guess).