Skip to content

Instantly share code, notes, and snippets.

@g-lok
Last active March 8, 2026 01:24
Show Gist options
  • Select an option

  • Save g-lok/52b0526ad705c1d4882207eb7d97632b to your computer and use it in GitHub Desktop.

Select an option

Save g-lok/52b0526ad705c1d4882207eb7d97632b to your computer and use it in GitHub Desktop.
Setup linux and terminal on windows

WSL2 Setup instructions

Pimp your windoze wsl2 with my omakse chef's choice setup

Chocolatey installs

use chocolatey to install the following:

choco install localsend
choco install alacritty
choco install docker-desktop
choco install nerd-fonts-jetbrainsmono
choco install obsidian

So docker is pretty easy to setup and it uses the wsl by default. localsend is a fantastic tool to send files and folders between all your devices. You need nerdfonts to use alacritty and my shell tools. That's my favorite one. Obsidian is the most powerful knowledge database I've ever used. A self-organizing system for notes, tasks, clippings, any kind of information any way you want. I recommend using it the way the CEO does: https://stephango.com/vault

Install WSL2 with Ubuntu

Open Powershell (terminal)

wsl --install   

Reboot. Start WSL2/Ubuntu, setup whatever it asks you to. Update:

sudo apt update && sudo apt full-upgrade -y

Getting WSL ready

Launch the WSL2 terminal and enter the following:

sudo apt update
sudo apt upgrade
sudo apt install build-essential curl git
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Homebrew will give you 3 commands to get it setup in your path. These will be used temporarily. It will be something along the lines of:

echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.bashrc
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

make sure it works with brew help.

Install gum

brew install gum

Download my dotfiles setup

Ok these haven't been formalized for linux yet but there's still enough there to do most of the heavy lifting.

Create a directory for git clones and dotfiles:

mkdir ~/gitclones
mkdir ~/dotfiles

cd into gitclones and clone my repo:

cd ~/gitclones/
git clone https://github.com/g-lok/gs-dotfiles.git

Install all the cli tools

cd ~/gitclones/gs-dotfiles/install.d/macos/
brew bundle install --file Brewfile-terminal-apps
brew install zellij
brew install opencode
brew install windsurf
brew install jj
brew install lazygit
brew install lazydocker

Install lazyvim

mv ~/.config/nvim{,.bak}

# optional but recommended
mv ~/.local/share/nvim{,.bak}
mv ~/.local/state/nvim{,.bak}
mv ~/.cache/nvim{,.bak}

git clone https://github.com/LazyVim/starter ~/.config/nvim
rm -rf ~/.config/nvim/.git

Install oh-my-zsh and plugins

ZSH= sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

export ZSH_CUSTOM="$HOME/.oh-my-zsh/custom"

git -C "$ZSH_CUSTOM/plugins/zsh-autosuggestions" pull  || git clone https://github.com/zsh-users/zsh-autosuggestions.git "$ZSH_CUSTOM/plugins/zsh-autosuggestions"
git -C "$ZSH_CUSTOM/plugins/fzf-tab" pull || git clone https://github.com/Aloxaf/fzf-tab "$ZSH_CUSTOM/plugins/fzf-tab"
git -C "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" pull || git clone https://github.com/zsh-users/zsh-syntax-highlighting.git "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting"
git -C "$ZSH_CUSTOM/plugins/fast-syntax-highlighting" pull || git clone https://github.com/zdharma-continuum/fast-syntax-highlighting.git "$ZSH_CUSTOM/plugins/fast-syntax-highlighting"
git -C "$ZSH_CUSTOM/plugins/zsh-autocomplete" pull || git clone --depth 1 -- https://github.com/marlonrichert/zsh-autocomplete.git "$ZSH_CUSTOM/plugins/zsh-autocomplete"

Install some programming languages/tooling

You use mise to install languages/tooling and manage versions in your various projects. Here's we're installing some global packages that are good to have on your system.

mise use --global go@latest
mise use --global node@lts
mise use --global python@latest
mise plugins install poetry https://github.com/mise-plugins/mise-poetry.git
mise use --global poetry@latest
mise use --global ruby@latest
mise settings add idiomatic_version_file_enable_tools ruby
mise x ruby -- gem install rails --no-document
mise use --global rust
mise use --global zig@latest

copy dotfiles over - first round

This is where things get a little problematic because of linux and WSL2 but don't worry I already figured it all out.

cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/* ~/dotfiles/

Stow adopt your configs into ~/dotfiles/

What stow is going to do is copy any existing configuration files that are specified in the folders in ~/dotfiles and create symbolic links from the original locations to the ~/dotfiles directory. This means that everything will actually be sitting in one place despite the linked configs being scattered everywhere in their default locations, and you can even use git to version control your changes and sync them on other machines with github.com

First thing's first we have to edit the ~/dotfiles/dotfiles.sh script to just do stow stuff and not copy anything around. Use an editor like nvim or pico to comment out the cd commands and certain configs we don't want at the top of the file, like so:

#!/usr/bin/env bash
## Use GNU Stow to set dotfile configs

## Set current working directory to dotfiles folder
# cd "$(dirname "$0")" || exit 0
# pwd

OS=$(uname -s)
if [[ "$(uname -m)" == "arm64" ]]; then
  arch="arm64"
else
  arch="intel"
fi

## Get the script path while we're at it
# export GSDOT_DOTFILES_PATH=$(dirname "$(readlink -f "$0")")
# cp -rf "$GSDOT_DOTFILES_PATH"/* "$HOME/dotfiles/"
# cd "$HOME/dotfiles/"
stow_and_copy() {
  config=$1
  echo "GNU Stow Adopt/import dotfiles: $config"
  ## GNU Stow to set up non-OS specific configs
  ## stow adopt it first before anything to keep the user's existing configs safe
  stow --target="$HOME" --adopt "${config}" --override='.*'
  ## stow restow to make it clean
  stow --target="$HOME" --restow "${config}"
  # cp -rf "$GSDOT_DOTFILES_PATH/$config" "$HOME/dotfiles/"
}
## We doing this precise and intentional baby
GSDOT_UNIVERSAL=(
  # "alacritty"
  "bash"
  "btop"
  # "ghostty"
  "golangci"
  "neovim"
  "shellrc"
  "starship"
  # "VSCode"
  "yazi"
  "zellij"
  "zsh"
)

So nvim is absolutely incredible but it's really strange at first and has a learning curve, I get it. Here's the basics of what you need to make those changes:

  • cd ~/dotfiles/
  • nvim dotfiles.sh
  • let it install its stuff. you may need to press capital S in the lazy plugin manager window to sync everything up, and then restart it.
  • to exit type :q enter. Then nvim dotfiles.sh again.
  • Ok we're back in, here's the basics:
    • This is a modal editor, meaning there's lots of different "modes" that have their own commands and operations. You start in "normal" mode, which is the default baseline mode you'll spend most of your time in.
    • To get back to normal mode at any time, press ctrl+[ or Esc. ctrl+[ keeps you hands in place though.
    • Basic movement is h=left, j=down, k=up, l=right. The whole idea of vim is that it keeps you hands on the keyboard in regular typing position at all times. However arrow keys will also work.
    • To comment/uncomment a line, if in normal mode move to the line and type gcc.
    • To comment multiple lines, enter Visual Line mode from normal mode with Shift+V, then move up and down to select the lines. To comment a line selection in visual mode, type gc.
    • To edit/type text, use Insert Mode with i, then go back to normal mode.
    • Undo with u in normal mode.
    • To paste either pres p in normal mode, or enter insert mode and shift+ctrl+v
    • to copy, select text with either visual mode v, visual line mode with shift+V, and then press y to yank. Or quickly yank a whole line with yy.
    • delete with d. Delete a whole line with dd. Delete a whole file with ggdG (gg=goto top of file, d=delete, G=until end of file).
    • ctrl+e to make the autocomplete window go away.
    • Once you have commented the lines specified, save and exit by typing :wq enter.

ok now we run it.

./dotfiles.sh

When it asks you to select, select them all with ctrl+a and hit enter.

Ok everything should be stowed.

Replacing stowed files with our own.

cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/btop ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/golangci ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/neovim ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/shellrc ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/starship ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/yazi ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/zellij-linux ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/zellij-macos-intel ~/dotfiles/
cp -r ~/gitclones/gs-dotfiles/install.d/dotfiles/zsh ~/dotfiles/

Fixing stuff

Bash

nvim ~/dotfiles/bash/.bashrc and paste the following at the end:

if [ -t 1 ]; then
  if [ -d "$HOME"/.shellrc/ ]; then
    for file in "$HOME"/.shellrc/*.sh; do
      [ -e "$file" ] || break
      source "$file"
    done
  fi
fi
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)"

:wq and exit.

Homebrew

We got a bug here: nvim ~/.shellrc/00-PATH.sh

### Homebrew
## Figure out where brew is installed.
# BREW_BIN="/usr/local/bin/brew"
# if [ -f "/opt/homebrew/bin/brew" ]; then
#   BREW_BIN="/opt/homebrew/bin/brew"
# elif [ -f "/usr/local/bin/brew" ]; then
#   BREW_BIN="/usr/local/bin/brew"
# elif [ -f "$HOME/linuxbrew/.linuxbrew/bin/brew" ]; then

BREW_BIN="/home/linuxbrew/.linuxbrew/bin/brew"

# else
#   echo "brew binary not found."
# fi

Save and exit.

Preserve $PATH on sudo commands

We want access to our homebrew apps when using sudo. Edit ~/.shellenv/02-aliases.sh and add the following alias:

alias sudo='sudo env PATH="$PATH"'

Save and exit.

Fix ugly color highlighting on dir autocomplete

Add this to the bottom of ~/.zshrc:

# Set custom colors for ls and completion
export LS_COLORS='fi=00:mi=00:mh=00:ln=01;36:or=01;31:di=01;34:ow=04;01;34:st=34:tw=04;34:'
LS_COLORS+='pi=01;33:so=01;33:do=01;33:bd=01;33:cd=01;33:su=01;35:sg=01;35:ca=01;35:ex=01;32'

# Ensure completion uses the same colors as ls
zstyle ':completion:*' list-colors "${(@s.:.)LS_COLORS}"

Save and exit.

Zellij

I'm not sure if yours will do this but my zellij got linked to the wrong config.

Edit its config: nvim ~/.config/zellij/config.kdl

On around line 280 it should be:

default_shell "/home/linuxbrew/.linuxbrew/bin/zsh"

Save and exit.

Add my neovim plugins

nvim ~/.config/nvim/lazyvim.json

make it like this:

{
  "extras": [
    "lazyvim.plugins.extras.coding.mini-comment",
    "lazyvim.plugins.extras.coding.mini-surround",
    "lazyvim.plugins.extras.coding.yanky",
    "lazyvim.plugins.extras.editor.dial",
    "lazyvim.plugins.extras.editor.inc-rename",
    "lazyvim.plugins.extras.editor.mini-files",
    "lazyvim.plugins.extras.lang.ansible",
    "lazyvim.plugins.extras.lang.cmake",
    "lazyvim.plugins.extras.lang.docker",
    "lazyvim.plugins.extras.lang.git",
    "lazyvim.plugins.extras.lang.go",
    "lazyvim.plugins.extras.lang.helm",
    "lazyvim.plugins.extras.lang.json",
    "lazyvim.plugins.extras.lang.markdown",
    "lazyvim.plugins.extras.lang.php",
    "lazyvim.plugins.extras.lang.python",
    "lazyvim.plugins.extras.lang.ruby",
    "lazyvim.plugins.extras.lang.rust",
    "lazyvim.plugins.extras.lang.sql",
    "lazyvim.plugins.extras.lang.terraform",
    "lazyvim.plugins.extras.lang.toml",
    "lazyvim.plugins.extras.lang.yaml",
    "lazyvim.plugins.extras.lang.zig",
    "lazyvim.plugins.extras.test.core",
    "lazyvim.plugins.extras.util.dot",
    "lazyvim.plugins.extras.util.mini-hipatterns"
  ],
  "install_version": 8,
  "news": {
    "NEWS.md": "11866"
  },
  "version": 8
}

Save with :w

Install everything by pressing <leader>l (<leader> is spacebar by default), then capital S, then q to quit when it's done.

Almost there.

Ok I think we got most of this working. Change to the zsh shell:

zsh

You should see a fancy shell with nice colors. If you don't we missed something, hit me up.

Setting up default shell

We want to use zsh with zellij as our primary shell.

Edit the WSl's "approved" shell list:

sudo nvim /etc/shells

Go to bottom line, press o to create a new line underneath in insert mode, and add:

/home/linuxbrew/.linuxbrew/bin/zsh
/home/linuxbrew/.linuxbrew/bin/zellij

Save and exit.

Set the default shell to the zellij session manager:

 chsh -s $(which zellij)

Set up alacritty

Alacritty weirdly doesn't come with its config by default, so we're going to make one:

cd /mnt/c/Users/<yourusername>/Application\ Data/
mkdir alacritty
nvim alacritty/alacritty.toml

Copy this into it:

[terminal.shell]
program = "C:\\Windows\\System32\\wsl.exe"

[font]
normal = { family = "JetBrainsMono Nerd Font Mono", style = "Regular" }
size = 12

[window]
option_as_alt = "Both"

[colors.primary]
background = "#1e1e2e"
foreground = "#cdd6f4"
dim_foreground = "#7f849c"
bright_foreground = "#cdd6f4"

[colors.cursor]
text = "#1e1e2e"
cursor = "#f5e0dc"

[colors.vi_mode_cursor]
text = "#1e1e2e"
cursor = "#b4befe"

[colors.search.matches]
foreground = "#1e1e2e"
background = "#a6adc8"

[colors.search.focused_match]
foreground = "#1e1e2e"
background = "#a6e3a1"

[colors.footer_bar]
foreground = "#1e1e2e"
background = "#a6adc8"

[colors.hints.start]
foreground = "#1e1e2e"
background = "#f9e2af"

[colors.hints.end]
foreground = "#1e1e2e"
background = "#a6adc8"

[colors.selection]
text = "#1e1e2e"
background = "#f5e0dc"

[colors.normal]
black = "#45475a"
red = "#f38ba8"
green = "#a6e3a1"
yellow = "#f9e2af"
blue = "#89b4fa"
magenta = "#f5c2e7"
cyan = "#94e2d5"
white = "#bac2de"

[colors.bright]
black = "#585b70"
red = "#f38ba8"
green = "#a6e3a1"
yellow = "#f9e2af"
blue = "#89b4fa"
magenta = "#f5c2e7"
cyan = "#94e2d5"
white = "#a6adc8"

[[colors.indexed_colors]]
index = 16
color = "#fab387"

[[colors.indexed_colors]]
index = 17
color = "#f5e0dc"

Save and exit (:wq)

OK we're done

Whew ok we made it.

exit this shell let's give this a whirl.

How to use

  • Launch Alacritty from your start menu
  • Maximize it
  • You should see a shell with a green border and a welcome screen from zellij. press esc to make it go away.
  • zellij is a session manager like tmux. You can create multiple sessions, save them and pick up from later, and manage panes, tabs, stacks, floating windows, all kinds of stuff. Check out their walkthroughs on the homepage.
    • zellij is configured to be in lock mode by default to avoid keymap conflicts.
    • unlock it with ctrl+g
    • press p for panels
    • press r to create a split panel to the right.
    • press ctrl+g to unlock it again
    • press p for panel, then d to split the right panel down.
    • quick navigation between panels in lock mode uses ctrl+shift+ either vim motions (hjkl) or the arrow keys.
    • while in the lower right panel, press ctrl+g, p, s to create a stack.
    • move up and down stacks by moving up and down.
    • most of the important key maps will be displayed on the bottom bar, but the full key maps can be seen in the zellij config in ~/.config/zellij/config.kdl

This has a lot of cool toys built in. Here are some highlights:

  • lazyvim obviously. together with zellij and alacritty, the stars of the show.
  • autocomplete and fzf (fuzzy finder) built into everything. Autocomplete with the tab key, fuzzy find is built in.
  • smart command history. Press up or down to cycle history. Enter a partial command to cycle history through anything that starts with that partial command.
  • yazi for file management
  • zoxide replaces cd. Every time you cd into a folder, it creates an index that you can quickly reference from anywhere. For example, now that we've been there already, you can probably just type cd dotf to go to the dotfiles directory, or cd gs dot to go my gs-dotfiles git repo.
  • lazygit and lazydocker for awesome git/docker management. Learn git from ThePrimeagen with this great free course: https://youtu.be/rH3zE7VlIMs?si=PtIbL-UPwx6qvv4t.
  • mise for programming tooling and environment management
  • starship for the terminal prompt. Don't like mine? Use starship to either pick another one or create your own.
  • jj (jujutsu), an experimental abstraction on top of git that makes it much more intuitive, seamless, easy, flexible, etc. Just better. https://youtu.be/mM4nrhDenC8
  • opencode for most Ai prompt and agentic tooling duties. Windsurf for better AI-powered inline suggestions in neovim. They have a free tier.
  • ripgrep (rg) for faster better grep duties.
  • btop for better system monitoring.
  • see all the aliases I set up with alias.
  • hledger - unlock the power of cli tooling and plaintext markdown for your finances.
  • brew for installing cli apps.
    • update installed apps with brew update && brew upgrade

Just look through the ~/gitclones/gs-dotfiles/install.d/macos/Brewfile-terminal-apps file to see what I installed, there's things for everything in there.

Awesome free books

You don't need to know everything about the terminal, but you should learn the basics and pick up important tools like sed, awk, xargs, rg, etc, basic piping and redirects, output or append to file, etc. Here's the book that taught me the command line: https://linuxcommand.org/tlcl.php

This is the best, the ONLY book on how to use lazyvim, and it was the key that finally unlocked the power of vim for me after decades of "not getting it". Incredible book, is the best way to learn it other than just using it and searching whenever you have a question about how to do something. It comes pre-baked with an absolute shit ton of incredible tools from a wide variety of plugin developers, and it has everything pre-configured. That being said, both the author and myself have contributed some modifications of our own in the ~/.config/nvim/lua/plugins/ folder. This is where you put your own custom stuff, like if you want to integrate windsurf for example, or make/change any keybindings.

https://lazyvim-ambitious-devs.phillips.codes/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment