Introduction
This is a personal wiki that I'm building almost out of spite. As-of 2024, I've moved to using a terminal full-time, and with this I've built up an environment for myself that I enjoy using. Unforfunately, this env includes various slightly off-piste tools, some of which are pre-1.0, and this has resulted into a cascade of issues that I run into and have to resolve.
From all of this, I've decided to build this wiki to document all of these issues and, primarily, how I've either fixed or worked around them. This will not be limited to just these env issues that have spured me to make this - I have continuously run into annoying issues with many things I work with and these will be documented the same. While this is mostly for myself, if someone else finds this useful then maybe all this frustration and suffering isn't all for nothing.
Software Development
Many things here are the reason I built this wiki in the first place.
This is the current environment I'm using:
- Shell: Nushell
- Terminal: WezTerm
- Package manager: Homebrew
- Including on Linux, where I use it to keep things consistent & up-to-date
- Git repository store: GitHub
- CI/CD pipeline: GitHub Actions
- Dotfile/config management: chezmoi
- Editor: Helix
- Git UI: lazygit
- Keychain: GnuPG
- Default language: Rust
- Container system: Docker
- Notetaking: Obsidian (with iCloud Drive sync)
Learning to program
I've had various thoughts on how I'd recommend learning to program in the first place. The most challenging thing is that I've been writing code for so long it's hard to put myself into the shoes of someone who's never seen code before. My best recommendations so far is this:
- Start with a simple, dynamically-typed language
- Pick one based on the sort of things you'd want to make
- JavaScript for web-dev, Python for data-processing or desktop GUI apps
- Make things you want to use
- Creating things for the sake of learning how is not how I personally work
- I'll only start writing code when I want to make something useful
- Switch to statically typed language sooner-rather-than-later
- Static types are essential for any moderately-sized project or larger
- Things like C# (C-sharp) (my beloved) or Java (my beloathed) are good to start with
- While I love Rust, it's really hard to start with and only recommended if you're already decent at programming
- C++ is still used in older projects, but is starting to head out with newer ones
- Go is simple to start with and well supported
- Start with Visual Studio Code as editor
- Nearly everything supports it
- Tons of extensions
- Very well supported
- Learn how to use a terminal
- Most programming tools only work in the terminal
- Many need at least a glacing familiarity to be installed and used
- Knowing the basics of a POSIX-compliant shell is very useful
- Most GNU/Linux systems use
bash
- macOS uses
zsh
- Most GNU/Linux systems use
- Learn Docker
- Not immediately, but fairly soon
- Most software deployment is done via this now
- Podman technically works but is not a drop-in replacement (despite what may be implied)
- Learn C
- Write something in it
- It's the lingua franca of the software world - nearly all languages support interoperability via C - so knowing how to read and write it is important
- Not necessary to write a lot, just enough to be able to understand FFIs
- Use GNU/Linux (or macOS if you already have it)
- Most software dev happens and it targeted here
- Windows can work, but using a unix-like system is typically expected in most places
- Linux distros are nearly all free as well, making for a low barrier to entry
- Ubuntu is the best place to start if you know nothing
To start learning to program, the main thing above all is to be comfortable researching something you don't know. There are a lot of concepts to pick up, and it's expected that you will have to look things up constantly to get by. I've already used multiple bits of jargon that a non-programmer won't understand, but this is supposed to be compact and a jumping-off-point, so I will not expand any of it here. Researching is a skill in-and-of itself, and it's important that any new programmer learns how to do it efficiently.
Nushell
- Still quite new, lots of little issues and incompatabilities
- Can function just fine as a login shell, but be aware of this
- Main thing to be aware of that many installers/tutorials that provide shell commands
assume a POSIX-compliant shell, which
nu
is not
- Nix doesn't work
- When set as a login shell, it won't load any config/env when executing a command
directly via SSH (e.g.
ssh hostname '$env.PATH'
)- nushell/nushell#10219
- Hacky workaround that I'm using in my own config:
# Executes a shell command on a remote machine using a nu login shell. # # TODO: This is a workaround; once there's a fix in nu this can be dropped. export def ssh-exec [host: string, cmd: string --tty (-t), ...rest: string]: nothing -> string { let macNu = "/opt/homebrew/bin/nu" let linuxNu = "/home/linuxbrew/.linuxbrew/bin/nu" ssh $host ...$rest $"^$\"\(if \('($macNu)' | path exists) { '($macNu)' } else { '($linuxNu)' })\" -l -c '($cmd)'" }
- As seen above,
highlight.js
does not support nu highlighting- TODO: open GH issue
- Excellent for playing around with data
- POSIX shells don't come close
- Needs some proper graphing tools
- TODO: either open GH issue or make/find something
Nix
- Need a custom env setup
- Currently using one based on the GH issue is the best workaround
- NixOS/nix#9813
nix-darwin
doesn't work at all- TODO: GH issue needs opening
WezTerm
- As of writing, very little work has been done on the project
- It looks like @wez is working on other things
- Even PRs which are ready to merge are going stale
- I personally might try fixing some of these issues, but little motivation until PR merging activity seems likely
- Domains struggle with resizing & more than 1 pane
- Best to close all but 1 pane in a tab before detaching, otherwise you'll need to do it anyway once reattached
- wez/wezterm#4723
- wez/wezterm#5117
- wez/wezterm#5142
- wez/wezterm#5165
- Tab order is not preserved if changed when in a domain
- TODO: open GH issue
- Unix domains require un-documented default first value
- Just needs
{ name = "some name for local domain" }
as first value forunix_domains
- TODO: needs a GH issue for improved docs
- Just needs
- SSH domains are nearly useless
- For very basic setups could work
- Built-in SSH doesn't support nearly anything in
~/.ssh/config
so anything like proxy-jumping or match statements don't work - Unix domains work over SSH via
proxy_command
and lets you use the real SSH client- e.g.
{ name = "<domain name>", proxy_command = { "ssh", "-T", "-A", "<ssh hostname>", "</path/to/wezterm>", "cli", "proxy", }, }
- e.g.
- No way to have WezTerm execute a command within a domain and return the result locally
- Would be useful for status bar
- TODO: open GH issue
- Keybinds on macOS are real blech by default
- Have rebuilt base keybinds (not key-tables) entirely based on what I used in iTerm
- Works very well, not public yet but want to make it so eventually
GitHub Actions/Workflows
- Workflows with multiple jobs do not share the same environment
- Each job starts on an entirely fresh env, including any checked-out files or built artefacts
- To share built outputs, something like actions/upload-artifact
should be used
- This wiki is deployed using this kind of system
- This is not necessarily the case with self-hosted runners, but it's best to assume it is for best compatibility