{"id":13572686,"url":"https://github.com/wincent/wincent","last_synced_at":"2025-05-14T19:02:57.700Z","repository":{"id":573875,"uuid":"205917","full_name":"wincent/wincent","owner":"wincent","description":"💾 Dot-files","archived":false,"fork":false,"pushed_at":"2025-04-10T08:16:12.000Z","size":196286,"stargazers_count":1159,"open_issues_count":6,"forks_count":104,"subscribers_count":51,"default_branch":"main","last_synced_at":"2025-04-10T09:28:11.688Z","etag":null,"topics":["clipper","dotfiles","iterm2","macos","tmux","vim"],"latest_commit_sha":null,"homepage":"","language":"Vim Script","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"headzoo/ocean","license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wincent.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/base16-builder.rb","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2009-05-20T16:27:09.000Z","updated_at":"2025-04-10T08:05:59.000Z","dependencies_parsed_at":"2023-10-05T04:29:22.584Z","dependency_job_id":"feb1262a-4ba7-4aa7-88f4-24571f6cd73b","html_url":"https://github.com/wincent/wincent","commit_stats":{"total_commits":4973,"total_committers":12,"mean_commits":414.4166666666667,"dds":"0.0028152020912929343","last_synced_commit":"875ea7febfbd90abe6f94d49c1aa53b57db91766"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wincent%2Fwincent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wincent%2Fwincent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wincent%2Fwincent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wincent%2Fwincent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wincent","download_url":"https://codeload.github.com/wincent/wincent/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248717240,"owners_count":21150387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clipper","dotfiles","iterm2","macos","tmux","vim"],"created_at":"2024-08-01T14:01:32.614Z","updated_at":"2025-05-14T19:02:57.690Z","avatar_url":"https://github.com/wincent.png","language":"Vim Script","readme":"# \"dotfiles\" and system configuration\n\n![CI status badge](https://github.com/wincent/wincent/workflows/ci/badge.svg)\n\n\u003e These dotfiles are affectionately dedicated to the vi editor originally created by Bill Joy, with whom I have spent many pleasant evenings[^1]\n\n— Greg Hurrell, [paraphrasing Donald Knuth](https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming)\n\n## Overview\n\n![screenshot](https://raw.githubusercontent.com/wincent/wincent/media/screenshot.png)\n\n- Target platforms: macOS and Linux (see [Platform status](#platform-status) below).\n- Set-up method: ~~Beautiful and intricate snowflake~~ an incredibly over-engineered custom configuration framework called [Fig](./fig/README.md).\n- Visible in the screenshot:\n  - [The \"classic-dark\"](https://github.com/tinted-theming/schemes/blob/spec-0.11/base16/classic-dark.yaml) color scheme (see [screenshots of other colorschemes](https://github.com/wincent/wincent/blob/media/colorschemes/README.md)).\n  - [Adobe Source Code Pro](https://github.com/adobe-fonts/source-code-pro) (Light) font.\n  - [Neovim](https://neovim.io), running inside [tmux](https://github.com/tmux/tmux), inside [kitty](https://sw.kovidgoyal.net/kitty/), on macOS \"Sonoma\".\n\n## Features\n\n### Dotfiles\n\n[A set of dotfiles](https://github.com/wincent/wincent/tree/main/aspects/dotfiles/files) that I've been tweaking and twiddling since the early 2000s ([under version control](https://github.com/wincent/wincent/commit/61a7e2a830edb7) since 2009). Characteristics include:\n\n- Sane Vim pasting via bracketed paste mode.\n- Write access to local clipboard from local and remote hosts, inside and outside of tmux (via [Clipper](https://github.com/wincent/clipper)).\n- Full mouse support (pane/split resizing, scrolling, text selection) in Vim and tmux.\n- Focus/lost events for Vim inside tmux.\n- Cursor shape toggles on entering Vim.\n- Italics in the terminal.\n- Bundles a (not-excessive) number of [useful Vim plug-ins](https://github.com/wincent/wincent/tree/main/aspects/nvim/files/.config/nvim/pack/bundle/opt).\n- Conservative Vim configuration (very few overrides of core functionality; most changes are unobtrusive enhancements; some additional functionality exposed via `\u003cLeader\u003e` and `\u003cLocalLeader\u003e` mappings.\n- Relatively restrained Zsh config, Bash-like but with a few Zsh perks, such as right-side prompt, auto-cd hooks, command elapsed time printing and such.\n- Unified color-handling (across Kitty, Neovim, etc) via [tinted-theming/tinted-kitty](https://github.com/tinted-theming/tinted-kitty), [tinted-theming/tinted-shell](https://github.com/tinted-theming/tinted-shell), [tinted-theming/tinted-tmux](https://github.com/tinted-theming/tinted-tmux), [tinted-theming/tinted-vim](https://github.com/tinted-theming/tinted-vim), and [wincent/base16-nvim](https://github.com/wincent/base16-nvim).\n- Encrypted versioning of files with sensitive content (via [git-cipher](https://github.com/wincent/git-cipher)).\n- Comprehensive [Hammerspoon](http://www.hammerspoon.org/) [config](https://github.com/wincent/wincent/tree/main/aspects/dotfiles/files/.hammerspoon).\n\n### Homebrew\n\nOn macOS, [the \"homebrew\" aspect](https://github.com/wincent/wincent/tree/main/aspects/homebrew) installs [a bunch of useful software](https://github.com/wincent/wincent/blob/main/aspects/homebrew/templates/Brewfile.erb).\n\n### Keyboard customization\n\nOn macOS, we use [Karabiner-Elements](https://github.com/tekezo/Karabiner-Elements/), and on Linux, we use [Interception Tools](https://gitlab.com/interception/linux/tools) and a few other pieces to make the following changes:\n\n- Make Caps Lock serve as Backspace (when tapped) and Left Control (when chorded with another key). When held down alone, Caps Lock fires repeated Backspace events.\n- Make Return serve as Return (when tapped) and Right Control (when chorded with another key). When held down alone, Return fires repeated Return events.\n- Toggle Caps Lock on by tapping both Shift keys simultaneously.\n- Makes the function keys on my external Realforce keyboard behave like the \"media\" keys on Apple's keyboards.\n\nAnd these only on macOS:\n\n- Swap Option and Command keys on my external Realforce keyboard.\n- Make the \"application\" key (extra modifier key on right-hand side) behave as \"fn\" on Realforce keyboard.\n- Map Control-I to F6 (only in the terminal) so that it can be mapped independently from Tab in Vim[^linux].\n- Make \"pause\" (at far-right of function key row) behave as \"power\" (effectively, sleep) on Realforce keyboard.\n- Adds a \"SpaceFN\" layer that can be activated by holding down Space while hitting other keys; I use this to make the cursor keys available on or near the home row in any app.\n\n[^linux]: This isn't needed on Linux because we can achieve the same via a Kitty configuration.\n\n### Zsh\n\n#### Functions\n\n- `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).\n- `bounce`: bounce the macOS Dock icon if the terminal is not in the foreground.\n- `color`: change terminal and Vim color scheme.\n- `fd`: \"find directory\" using fast `bfs` and `sk`; automatically `cd`s into the selected directory.\n- `fh`: \"find [in] history\"; selecting a history item inserts it into the command line but does not execute it.\n- `history`: overrides the (tiny) default history count.\n- `jump` (aliased to `j`): to jump to hashed directories.\n- `regmv`: bulk-rename files (eg. `regmv '/\\.tif$/.tiff/' *`).\n- `scratch`: create a random temporary scratch directory and `cd` into it.\n- `tick`: moves an existing time warp (eg. `tick +1h`); see `tw` below for a description of time warp.\n- `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).\n- `tw` (\"time warp\"): overrides `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` (eg. `tw -1d`).\n\n#### Prompt\n\nZsh is configured with the following prompt:\n\n![Zsh prompt](https://raw.githubusercontent.com/wincent/wincent/media/prompt.png)\n\nVisible here are:\n\n- Concise left-hand prompt consisting of:\n  - Last component of current directory (abbreviates `$HOME` to `~` if possible).\n  - Prompt marker, `❯`, the \"[HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT](https://codepoints.net/U+276F)\" (that's `\\u276f`, or `e2 9d af` in UTF-8).\n- Extended right-hand size prompt which auto-hides when necessary to make room for long commands and contains:\n  - Duration of previous command in adaptive units (seconds, minutes, hours, days, depending on duration).\n  - Current version control branch name.\n  - Current version control worktree status using colors that match those used in `git status`:\n    - Green dot indicates staged changes.\n    - Red dot indicates unstaged changes.\n    - Blue dot indicates untracked files.\n  - Full version of current working directory (again, abbreviating `$HOME` to `~`).\n\nNested shells are indicated with additional prompt characters. For example, one nested shell:\n\n![Zsh prompt with one nested shell](https://raw.githubusercontent.com/wincent/wincent/media/prompt-shlvl-2.png)\n\nTwo nested shells:\n\n![Zsh prompt with two nested shells](https://raw.githubusercontent.com/wincent/wincent/media/prompt-shlvl-3.png)\n\nRoot shells are indicated with a different color prompt character and the word \"root\":\n\n![Zsh prompt with root shell](https://raw.githubusercontent.com/wincent/wincent/media/prompt-root.png)\n\nNesting within a root shell is indicated like this:\n\n![Zsh root prompt with one nested shell](https://raw.githubusercontent.com/wincent/wincent/media/prompt-root-shlvl-2.png)\n\nTwo nested shells:\n\n![Zsh root prompt with two nested shells](https://raw.githubusercontent.com/wincent/wincent/media/prompt-root-shlvl-3.png)\n\nIf the last command exited with a non-zero status (usually indicative of an error), a yellow exclamation is shown:\n\n![Zsh prompt showing command with non-zero exit status](https://raw.githubusercontent.com/wincent/wincent/media/prompt-error.png)\n\nIf there are background processes, a yellow asterisk is shown:\n\n![Zsh prompt showing background proceses](https://raw.githubusercontent.com/wincent/wincent/media/prompt-bg.png)\n\n## Dependencies\n\n- [tmux](https://github.com/tmux/tmux) 3.2 or later.\n- [Neovim](https://neovim.io) generally tracking the [latest release and sometimes the nightly](https://github.com/neovim/neovim/releases).\n- Relatively recent [Zsh](http://www.zsh.org/).\n- Relatively recent [Git](http://git-scm.com/).\n- [Clipper](https://github.com/wincent/clipper) for transparent access to the local system clipboard.\n- [Kitty](https://sw.kovidgoyal.net/kitty/).\n- [Ruby](https://www.ruby-lang.org/).\n- [Adobe Source Code Pro](https://github.com/adobe-fonts/source-code-pro) or any other fixed-width font that includes the [Powerline glyphs](http://powerline.readthedocs.io/en/master/installation.html#fonts-installation).\n\n## Platform status\n\n| Platform                               | Status                                                                                                                                            |\n| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n| macOS                                  | :1st_place_medal: Currently the most tested platform, as well as the one with most aspects (because my daily driver is macOS 13 \"Sonoma\")         |\n| Arch Linux                             | :2nd_place_medal: Less tested, fewer aspects involved, but likely to evolve in the future as I'm using Arch Linux on my \"leisure\" desktop machine |\n| Red Hat Linux and related (eg. CentOS) | :skull: Abandoned, but in the past (2011-2018) this was the distro I used full-time at work                                                       |\n\n## Installation\n\n### Clone\n\nDevelopment 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](./support/hooks/pre-push) (which updates the local branch) and [a post-receive hook](./support/hooks/post-receive) (which updates the remote).\n\n#### macOS\n\n```sh\ngit clone --recursive https://github.com/wincent/wincent.git\n```\n\n#### Arch Linux\n\n```sh\nsudo pacman -Syu\nsudo pacman -S git ruby tmux vim\ngit clone --recursive https://github.com/wincent/wincent.git\n```\n\n- `git`: In order to clone the repo.\n- `ruby`: So that git-cipher can run (also used to build Command-T).\n- `tmux`: Just for comfort (eg. so you can see scrollback).\n- `vim`: Because the `nvim` aspect needs Vim (it runs `vim` to do a `:helptags` update).\n\n### Install\n\n\u003e ⚠️ **WARNING:** There are _lots_ of different things that can be installed or configured (see [the `aspects/` directory](./aspects)). 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\"](./aspects/dotfiles) and [\"nvim\"](./aspects/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](./LICENSE.md), unless otherwise indicated).\n\nAt the time of writing, these are the aspects, which you can expect to change over time (see [the `aspects/` directory](./aspects) for an up-to-date listing):\n\n- On macOS only:\n  - **automator**: Scripts for use with Automator\n  - **automount**: Sets up macOS's automount facility\n  - **backup**: Backup scripts\n  - **cron**: Sets up cron files\n  - **defaults**: Sets up defaults (ie. preferences) on macOS\n  - **fonts**: Installs Source Code Pro font files\n  - **homebrew**: Installs and updates Homebrew\n  - **karabiner**: Configures Karabiner-Elements (keyboard customization).\n  - **launchd**: Configures launchd\n  - **nix**: Installs packages via the Nix package manager.\n  - **node**: Installs Node.js\n  - **ruby**: Installs Ruby gems\n  - **ssh**: Manages local SSH config\n  - **violentmonkey**: Sets up UserScripts\n- On Linux only:\n  - **aur**: Installs packages from the Arch User Repository.\n  - **avahi**: Manages the Avahi zeroconf (\"Bonjour\") networking daemon.\n  - **interception**: Sets up Interceptions Tools (keyboard customization).\n  - **locale**: Sets up /etc/locale.conf\n  - **pacman**: Installs packages via the Pacman package manager\n  - **sshd**: Manages sshd.\n  - **systemd**: Set up services that run from systemd\n- On both macOS and Linux:\n  - **dotfiles**: Creates symlinks in \\$HOME to the dotfiles in this repo\n  - **meta**: Tests the configuration framework\n  - **shell**: Sets the use shell to zsh\n  - **nvim**: Configures Neovim and Vim\n\n#### Examples\n\n```sh\n./install dotfiles nvim     # Just install \"dotfiles\" and \"nvim\" stuff.\n./install dotfiles          # Just install \"dotfiles\".\n./install dotfiles --step   # Prompt for confirmation at each step.\n./install dotfiles --check  # Do a dry-run, showing what would be changed.\n./install                   # Install everything.\n./install ^homebrew         # Install everything except for the \"homebrew\" aspect.\n./install --help            # Lists all aspects, descriptions, options.\n```\n\nThis sets up a local Node environment using [n](https://github.com/tj/n), and then uses [Fig](./fig/README.md) to copy the dotfiles and configure the machine.\n\n**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:\n\n```sh\ngit config --file ~/.config/git/config.local user.name \"John Doe\"\ngit config --file ~/.config/git/config.local user.email johndoe@example.com\n```\n\n### Running Neovim nightly\n\nOccasionally I need to switch to [a nightly release of Neovim](https://github.com/neovim/neovim/releases) in order to get access to unreleased features. I do this by installing a copy of the nightly under `vendor/`; for example, on macOS:\n\n```sh\nwget https://github.com/neovim/neovim/releases/download/nightly/nvim-macos-arm64.tar.gz\nsha256sum nvim-macos-arm64.tar.gz\nxattr -c nvim-macos-arm64.tar.gz\ntar xzvf nvim-macos-arm64.tar.gz\nrm nvim-macos-arm64.tar.gz\n```\n\n### Troubleshooting\n\n#### General troubleshooting\n\nThere are a few useful `./install` options:\n\n```sh\n# Run in \"check\" (dry-run) mode.\n./install --check\n\n# Show debugging information during the run.\n./install --debug\n\n# Confirm each task before running it (--step), and begin\n# execution from a specific task (--start-at-task) in a\n# specific aspect (\"dotfiles\").\n./install --step --start='make directories' dotfiles\n```\n\n#### `./install` hangs on the first run\n\nIf 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.\n\n[^lecture]: See `man sudoers`.\n\nTo avoid this, one time only, run `sudo -v` before running `./install`.\n\n## License\n\nUnless otherwise noted, the contents of this repo are in the public domain. See the [LICENSE](LICENSE.md) for details.\n\n## Authors\n\nThe repo is written and maintained by Greg Hurrell \u0026lt;[greg@hurrell.net](mailto:greg@hurrell.net)\u0026gt;. Other contributors that have submitted patches include, in alphabetical order:\n\n- Anton Kastritskiy\n- Hashem A. Damrah\n- Joe Lencioni\n- Jonathan Wilkins\n- Keng Kiat Lim\n- Mark Stenglein\n- Matthew Byrne\n- Michael Lohmann\n- Stone C. Lasley\n- Victor Igor\n- Zac Collier\n\nThis list produced with:\n\n    :read !git shortlog -s HEAD | grep -v 'Greg Hurrell' | cut -f 2-3 | sed -e 's/^/- /'\n\n## Security\n\nAs of [commit ec49be762ff3](https://github.com/wincent/wincent/commit/ec49be762ff3ef0570a9bc27f972d0d1f025e3da) (\"feat(dotfiles): automatically sign commits on personal machines\", 2022-06-19) and [commit 97143b5d7635](https://github.com/wincent/wincent/commit/97143b5d7635db0c71bb46085db99ebb6039afa9) (\"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.\n\nGitHub 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:\n\n```\ngpg: Signature made Mon 11 Jul 2022 11:50:35 CEST\ngpg:                using RSA key B0C9C204D656540BDCDA86229F6B84B5B1E9955E\ngpg:                issuer \"wincent@github.com\"\ngpg: Can't check signature: No public key\n```\n\nNote that the key fingerprint that you see in the commit is usually a subkey, signed by a primary key, which is kept offline as described in [\"GPG key rotation notes\"](https://wincent.dev/wiki/GPG_key_rotation_notes). In the example above, you can search a keyserver using either the subkey fingerprint that appears in the commit ([B0C9C204D656540BDCDA86229F6B84B5B1E9955E](https://keyserver.ubuntu.com/pks/lookup?search=B0C9C204D656540BDCDA86229F6B84B5B1E9955E+\u0026fingerprint=on\u0026op=index)) or the primary key fingerprint ([2F4469E0C1FA72AAC0A560C962106B56923F3481](https://keyserver.ubuntu.com/pks/lookup?search=2F4469E0C1FA72AAC0A560C962106B56923F3481+\u0026fingerprint=on\u0026op=index)), if you happen to know it, and you'll see that _both_ keys are listed in the search result, with _all_ subkeys (not just the one you searched for) listed underneath the primary key.\n\nYou can obtain the latest and full versions of the public keys with the following:\n\n```\n# Either, download directly given the key fingerprint as shown by Git:\ngpg --keyserver pgp.mit.edu --recv-key 4282ED4A05CC894D53A541C3F962DC1A1941CCC4 # greg@hurrell.net\ngpg --keyserver pgp.mit.edu --recv-key CA35A4528D888CDF264D0A2A4838AEDCA8CE883C # greg.hurrell@datadoghq.com\ngpg --keyserver pgp.mit.edu --recv-key 2F4469E0C1FA72AAC0A560C962106B56923F3481 # wincent@github.com\n\n# Same, but using an alternate keyserver:\ngpg --keyserver keyserver.ubuntu.com --recv-key 4282ED4A05CC894D53A541C3F962DC1A1941CCC4 # greg@hurrell.net\ngpg --keyserver keyserver.ubuntu.com --recv-key CA35A4528D888CDF264D0A2A4838AEDCA8CE883C # greg.hurrell@datadoghq.com\ngpg --keyserver keyserver.ubuntu.com --recv-key 2F4469E0C1FA72AAC0A560C962106B56923F3481 # wincent@github.com\n\n# Or, chose from a list of possible matches returned by searching for an email address:\ngpg --keyserver pgp.mit.edu --search-keys greg@hurrell.net\ngpg --keyserver pgp.mit.edu --search-keys greg.hurrell@datadoghq.com\ngpg --keyserver pgp.mit.edu --search-keys wincent@github.com\n\n# Same, but using an alternate keyserver:\ngpg --keyserver keyserver.ubuntu.com --search-keys greg@hurrell.net\ngpg --keyserver keyserver.ubuntu.com --search-keys greg.hurrell@datadoghq.com\ngpg --keyserver keyserver.ubuntu.com --search-keys wincent@github.com\n```\n\nYou can also grab the keys from GitHub, if you trust GitHub:\n\n```\n# Merely inspect:\ncurl https://github.com/wincent.gpg | gpg --show-keys\n\n# Actually import:\ncurl https://github.com/wincent.gpg | gpg --import\n```\n\nOnce you have those, Git will instead show:\n\n```\ngpg: Signature made Mon 11 Jul 2022 12:28:32 CEST\ngpg:                using RSA key B0C9C204D656540BDCDA86229F6B84B5B1E9955E\ngpg:                issuer \"wincent@github.com\"\ngpg: Good signature from \"Greg Hurrell \u003cwincent@github.com\u003e\" [unknown]\ngpg: WARNING: This key is not certified with a trusted signature!\ngpg:          There is no indication that the signature belongs to the owner.\nPrimary key fingerprint: 2F44 69E0 C1FA 72AA C0A5  60C9 6210 6B56 923F 3481\n     Subkey fingerprint: B0C9 C204 D656 540B DCDA  8622 9F6B 84B5 B1E9 955E\n```\n\nWhat's going on here, cryptographically speaking?\n\n- GPG keys consist of public and private parts, often referred to as public keys and private keys (together, a \"key pair\"). As the names suggest, the owner of the key must keep the private part secret, but the public part can be freely shared.\n- Roughly speaking, \"signing\" something means using the private key to encrypt a hash of the contents of the document that is being signed (in this case, the \"document\" is a commit).\n- The public key can be used to decrypt the hash, which can then be compared against the contents to confirm that they match. This is what is happening when we see `gpg: Good signature` above; it means that the public key for `Greg Hurrell \u003cwincent@github.com\u003e` verifies that the signature was indeed created with the corresponding private key belonging to that address.\n- Because only the owner has access to the private key, only the owner can make signatures with it; but conversely, because everybody has access to the public key, anybody can verify those signatures.\n- GPG keys have two additional concepts: \"subkeys\" are keys associated with a primary key; and \"usages\" describe what role those keys each play (eg. \"signing\", \"encryption\").\n- In practice, the primary key is always a \"signing\" key, and GPG will create one \"encryption\" subkey by default. Users can add/remove additional subkeys and assign them usages.\n- I create \"signing\" subkeys for making signatures and I rotate them once per year (I keep my primary key \"offline\" so that it can't be hacked if my machine is compromised).\n\nSo 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?\n\nThe 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\"](https://www.gnupg.org/gph/en/manual/x547.html) 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.\n\n[^1]: The evenings were spent with [vi](https://en.wikipedia.org/wiki/Vi) derivatives, not with Bill Joy.\n","funding_links":[],"categories":["Lua","Vim Script","vim","Credits"],"sub_categories":["Basic usage"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwincent%2Fwincent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwincent%2Fwincent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwincent%2Fwincent/lists"}