These dotfiles are affectionately dedicated to the vi editor originally created by Bill Joy, with whom I have spent many pleasant evenings[^1]
— Greg Hurrell, paraphrasing Donald Knuth
A set of dotfiles that I've been tweaking and twiddling since the early 2000s (under version control since 2009). Characteristics include:
<Leader>
and <LocalLeader>
mappings.On macOS, the "homebrew" aspect installs a bunch of useful software.
On macOS, we use Karabiner-Elements, and on Linux, we use Interception Tools and a few other pieces to make the following changes:
And these only on macOS:
[^linux]: This isn't needed on Linux because we can achieve the same via a Kitty configuration.
ag
: Transparently wraps the ag
executable so as to provide a centralized place to set defaults for that command (seeing as it has no "rc" file).bounce
: bounce the macOS Dock icon if the terminal is not in the foreground.color
: change terminal and Vim color scheme.fd
: "find directory" using fast bfs
and sk
; automatically cd
s into the selected directory.fh
: "find [in] history"; selecting a history item inserts it into the command line but does not execute it.history
: overrides the (tiny) default history count.jump
(aliased to j
): to jump to hashed directories.regmv
: bulk-rename files (eg. regmv '/\.tif$/.tiff/' *
).scratch
: create a random temporary scratch directory and cd
into it.tick
: moves an existing time warp (eg. tick +1h
); see tw
below for a description of time warp.tmux
: wrapper that reattches to pre-existing sessions, or creates new ones based on the current directory name; additionally, looks for a .tmux
file to set up windows and panes (note that the first time a given .tmux
file is encountered the wrapper asks the user whether to trust or skip it).tw
("time warp"): overrides GIT_AUTHOR_DATE
and GIT_COMMITTER_DATE
(eg. tw -1d
).Zsh is configured with the following prompt:
Visible here are:
$HOME
to ~
if possible).❯
, the "HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT" (that's \u276f
, or e2 9d af
in UTF-8).git status
:
$HOME
to ~
).Nested shells are indicated with additional prompt characters. For example, one nested shell:
Two nested shells:
Root shells are indicated with a different color prompt character and the word "root":
Nesting within a root shell is indicated like this:
Two nested shells:
If the last command exited with a non-zero status (usually indicative of an error), a yellow exclamation is shown:
If there are background processes, a yellow asterisk is shown:
Platform | Status |
---|---|
macOS | 🥇 Currently the most tested platform, as well as the one with most aspects (because my daily driver is macOS 13 "Sonoma") |
Arch Linux | 🥈 Less tested, fewer aspects involved, but likely to evolve in the future as I'm using Arch Linux on my "leisure" desktop machine |
Red Hat Linux and related (eg. CentOS) | 💀 Abandoned, but in the past (2011-2018) this was the distro I used full-time at work |
Development occurs on the main
branch, but to avoid inconvenience for people who previously cloned the repo when the master
branch was the main line, the legacy branch is kept up-to-date via a pre-push hook (which updates the local branch) and a post-receive hook (which updates the remote).
git clone --recursive https://github.com/wincent/wincent.git
sudo pacman -Syu
sudo pacman -S git ruby tmux vim
git clone --recursive https://github.com/wincent/wincent.git
git
: In order to clone the repo.ruby
: So that git-cipher can run (also used to build Command-T).tmux
: Just for comfort (eg. so you can see scrollback).vim
: Because the nvim
aspect needs Vim (it runs vim
to do a :helptags
update).⚠️ WARNING: There are lots of different things that can be installed or configured (see the
aspects/
directory). Unless you want your machine to be exactly like mine — which is unlikely — you probably don't want to install everything. Maybe you don't even want everything in the "dotfiles" and "nvim" aspects. Please inspect the contents of each aspect before proceeding to install it; you may even be better off just looking at the configuration files and stealing the bits that you find interesting or useful (everything is in the public domain, unless otherwise indicated).
At the time of writing, these are the aspects, which you can expect to change over time (see the aspects/
directory for an up-to-date listing):
./install dotfiles nvim # Just install "dotfiles" and "nvim" stuff.
./install dotfiles # Just install "dotfiles".
./install dotfiles --step # Prompt for confirmation at each step.
./install dotfiles --check # Do a dry-run, showing what would be changed.
./install # Install everything.
./install ^homebrew # Install everything except for the "homebrew" aspect.
./install --help # Lists all aspects, descriptions, options.
This sets up a local Node environment using n, and then uses Fig to copy the dotfiles and configure the machine.
Note: Given that ~/.config/git/config
is included with these dotfiles, any local modifications or overrides that you apply should be added to ~/.config/git/config.local
instead; for example:
git config --file ~/.config/git/config.local user.name "John Doe"
git config --file ~/.config/git/config.local user.email [email protected]
There are a few useful ./install
options:
# Run in "check" (dry-run) mode.
./install --check
# Show debugging information during the run.
./install --debug
# Confirm each task before running it (--step), and begin
# execution from a specific task (--start-at-task) in a
# specific aspect ("dotfiles").
./install --step --start='make directories' dotfiles
./install
hangs on the first runIf running on a brand new OS install where you have never used sudo
before, ./install
may appear to hang after requesting your password. This is because sudo
may show a "lecture"[^lecture] on first run that requires you to respond to a prompt. When running in the context of ./install
, you never see this prompt, because sudo
is running in a subprocess, which causes the run to hang.
[^lecture]: See man sudoers
.
To avoid this, one time only, run sudo -v
before running ./install
.
Unless otherwise noted, the contents of this repo are in the public domain. See the LICENSE for details.
The repo is written and maintained by Greg Hurrell <[email protected]>. Other contributors that have submitted patches include, in alphabetical order:
This list produced with:
:read !git shortlog -s HEAD | grep -v 'Greg Hurrell' | cut -f 2-3 | sed -e 's/^/- /'
As of commit ec49be762ff3 ("feat(dotfiles): automatically sign commits on personal machines", 2022-06-19) and commit 97143b5d7635 ("feat(dotfiles): sign commits everywhere except codespaces", 2022-06-20), I started signing most commits in this and other repos with GPG keys corresponding to my work and personal email addresses.
GitHub will label such commits with a "Verified" badge. In order to see signature information using the git
commandline executable, you would run commands such as git show --show-signature
and git log --show-signature
. Note that in order to be able to actually verify these signatures you need a copy of the corresponding public keys, otherwise Git will show:
gpg: Signature made Mon 11 Jul 2022 11:50:35 CEST
gpg: using RSA key B0C9C204D656540BDCDA86229F6B84B5B1E9955E
gpg: issuer "[email protected]"
gpg: Can't check signature: No public key
You can obtain the public keys with the following:
# Either, download directly given the key fingerprint as shown by Git:
gpg --keyserver pgp.mit.edu --recv-key C7C225A18975180C4485A1E070516DBB88E4F779
gpg --keyserver pgp.mit.edu --recv-key B0C9C204D656540BDCDA86229F6B84B5B1E9955E
# Or, chose from a list of possible matches returned by searching for an email address:
gpg --keyserver https://pgp.mit.edu/ --search-keys [email protected]
gpg --keyserver https://pgp.mit.edu/ --search-keys [email protected]
You can also grab the keys from GitHub, if you trust GitHub:
curl https://github.com/wincent.gpg | gpg --import
Once you have those, Git will instead show:
gpg: Signature made Mon 11 Jul 2022 12:28:32 CEST
gpg: using RSA key B0C9C204D656540BDCDA86229F6B84B5B1E9955E
gpg: issuer "[email protected]"
gpg: Good signature from "Greg Hurrell <[email protected]>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 2F44 69E0 C1FA 72AA C0A5 60C9 6210 6B56 923F 3481
Subkey fingerprint: B0C9 C204 D656 540B DCDA 8622 9F6B 84B5 B1E9 955E
What's going on here, cryptographically speaking?
gpg: Good signature
above; it means that the public key for Greg Hurrell <[email protected]>
verifies that the signature was indeed created with the corresponding private key belonging to that address.So those are the cryptographic primitives. The signature is "Good" in the cryptographic sense, but why the scary "WARNING"? It's because there's a whole other layer on top of this called the "web of trust". A good signature gives us the mathematical certainty that a particular private key was used to produce a given signature, but that tells us nothing about the human world that exists above and around that crypto. That is, the key was used to make the signature, but was it me who used the key? Am I really the handsome Australian man living in Madrid claiming to be Greg Hurrell, or am I in fact part of a clandestine criminal organization operating from a satellite-connected submarine in the Arctic sea?
The web of trust serves to link your human-level trust relationships to the underlying digital entities. By running gpg --edit-key $KEY
and hitting trust
, you can explicitly record your level of trust in any given key, and you can do things like going to "key signing parties" and such where you can physically meet people, verify their identity by whatever means you deem appropriate, and then sign one another's public keys. The accrued effect of these actions over time is to establish a web of connections where trust is transitively applied: if you trust A
and A
trusts B
, then you in turn can also trust B
. Having said all that, how to actually go about building a useful web of trust is beyond the scope of this README, and in all my long years on the internet, I've never once gone to a key signing event or otherwise engaged in activity that would help me integrate my keys into a useful web of trust.
[^1]: The evenings were spent with vi derivatives, not with Bill Joy.