···11-# --theme="Monokai Extended"
11+--theme="Monokai Extended"
2233# This is not supported on all terminal emulators (like tmux, by default)
44# --italic-text="always"
+11
.config/cargo/config.toml
···1313# "./target:/app/target",
1414# "test-runner-3ds:latest",
1515# ]
1616+[alias]
1717+# would be nice to make this default even for `cargo check` fully spelled out:
1818+c = "check --all-targets"
1919+cl = "clippy --all-targets"
2020+rr = "run --release"
2121+i = "install --locked"
2222+2323+w = "watch -w src,crates --command run --clear"
2424+2525+# This works slightly better than cargo-alias, but also only works on nightly :(
2626+aliases = "-Zunstable-options config get alias"
+11-6
.config/fish/completions/cargo.fish
···2626 end
2727end
28282929-# Check command works the same as b/build basically so we can reuse those completions
2929+# Check command works the same as b/build basically so we can reuse those completions. Fixed in 4.0
3030# https://github.com/fish-shell/fish-shell/pull/10499
3131for x in check c
3232 complete -c cargo -x -n "__fish_seen_subcommand_from $x" -l bench -a "(cargo bench --bench 2>&1 | string replace -rf '^\s+' '')"
···4747complete -c cargo -n "__fish_seen_subcommand_from 3ds" -f -a "$__fish_cargo_subcommands"
48484949# This might be easier with https://github.com/fish-shell/fish-shell/issues/7107
5050-# But for now we just sub in `check` for `clippy` and fallback to regular completions
5151-function __fish_cmdline_clippy_as_check
5050+function __fish_cmdline_replace_cmd -a orig_cmd new_cmd
5251 set -l cmd
5352 # Not sure exactly why this works, but sudo.fish completion also uses this pattern:
5453 set -l toks (commandline -opc) (commandline -ct)
5554 for tok in $toks
5656- if test "$tok" = clippy
5757- set tok check
5555+ if test "$tok" = $orig_cmd
5656+ set tok $new_cmd
5857 end
5958 set -a cmd $tok
6059 end
6160 string join -- " " $cmd
6261end
63626363+6464+# Aliases / clippy
6565+# Just sub in `check` for `clippy` and fallback to regular completions
6466complete -c cargo -n "__fish_seen_subcommand_from clippy" \
6565- -a '(complete --do-complete (__fish_cmdline_clippy_as_check))'
6767+ -a '(complete --do-complete (__fish_cmdline_replace_cmd clippy check))'
6868+6969+complete -c cargo -n "__fish_seen_subcommand_from t" \
7070+ -a '(complete --do-complete (__fish_cmdline_replace_cmd t test))'
+2
.config/fish/completions/git.exe.fish
···11+# Mainly for WSL things to work... I could probably do this more programmatically but meh
22+complete -c git.exe --wraps git
+21-6
.config/fish/conf.d/50-config.fish
···3636# Set jq to show null/true/false as magenta instead of black or otherwise
3737set -gx JQ_COLORS "1;35:1;35:1;35:0;39:0;32:1;39:1;39"
38383939+# Most of the default fish theme colors are fine, but escape sequences are a little too close
4040+# to some other colors; this makes them more like my editor
4141+set -g fish_color_escape "#AE81FF"
4242+3943# Use `bat` as pager if it present
4044if command -qs bat
4145 set -gx PAGER bat
···4852 set sed gsed
4953 end
50545151- # wewlad: https://github.com/sharkdp/bat/issues/652
5252- # Pending better support from bat, just strip all overstrike chars
5353- # and rely on the syntax highlighting instead of underscores/bold
5454- set -gx MANPAGER \
5555- "sh -c \"$sed -E -e 's#(.)\x08\1#\1#g' -e 's#_\x08(.)#\1#g' | bat --plain --language=Manpage\""
5555+ if command -qs batman
5656+ command batman --export-env | source
5757+ else
5858+ # wewlad: https://github.com/sharkdp/bat/issues/652
5959+ # Pending better support from bat, just strip all overstrike chars
6060+ # and rely on the syntax highlighting instead of underscores/bold
6161+ set -gx MANPAGER \
6262+ "sh -c \"$sed -E -e 's#(.)\x08\1#\1#g' -e 's#_\x08(.)#\1#g' | bat --plain --language=Manpage\""
6363+ end
5664end
57655866# https://stackoverflow.com/a/39352670
···8189 $DEVKITARM/bin \
8290 $DEVKITPRO/tools/bin \
8391 ~/.cargo/bin \
9292+ ~/.config/cargo/bin \
8493 ~/.local/share/rbenv/shims \
8594 ~/.local/bin \
8695 $GOPATH/bin \
···108117 # Any explicit nix store paths should remain at the front, most likely
109118 # introduced by e.g. `nix shell` or `nix develop`
110119 if string match --quiet -- '/nix/store/*' "$pth"
111111- fish_add_path --global --prepend --move "$pth"
120120+ fish_add_path --global --prepend --move --path "$pth"
112121 end
122122+end
123123+124124+# interactiveShellInit seems to be usable as its own sourceable file to do this
125125+# automatically in some later nixpkgs but for now just gonna add this manually
126126+if not contains /etc/fish/generated_completions -- $fish_complete_path
127127+ set -a fish_complete_path /etc/fish/generated_completions
113128end
114129115130# https://github.com/nix-community/home-manager/issues/5602
-1
.config/fish/conf.d/51-envs.fish
···6677set -Ux PYENV_VIRTUALENV_DISABLE_PROMPT 1
8899-109if status is-interactive
1110 # TODO: rtx activation can be inlined here, and replace pyenv/rbenv ideally
1211 if command -qs rtx
+1-1
.config/fish/conf.d/55-events.fish
···2233function __set_color_theme --on-event fish_preexec
44 # On macOS, this can change dynamically, so re-evaluate every time
55- if test $YADM_OS = Darwin
55+ if test "$YADM_OS" = Darwin
66 if test "$(defaults read -g AppleInterfaceStyle 2>/dev/null)" != Dark
77 set -gx COLOR_THEME light
88 else
+9
.config/fish/functions/find_completions.fish
···11+function find_completions
22+ for pth in $fish_complete_path
33+ set -l possible_completion "$pth/$argv[1].fish"
44+ if test -f $possible_completion
55+ echo $possible_completion
66+ break
77+ end
88+ end
99+end
+31-6
.config/fish/functions/fish_prompt.fish
···4545 set __fish_prompt_nix "$white""($nix_icon nix) $__fish_prompt_normal"
4646 end
47474848+ set -l __fish_prompt_direnv ""
4949+ if set -q DIRENV_USED
5050+ set -l direnv_dir (basename "$DIRENV_USED")
5151+ if string match -q "flake:*" -- "$DIRENV_USED"
5252+ set direnv_dir "$nix_icon $direnv_dir"
5353+ set __fish_prompt_nix ""
5454+ else
5555+ set direnv_dir " $direnv_dir"
5656+ end
5757+ set -l direnv_dir (string shorten --max 15 -- "$direnv_dir")
5858+ set __fish_prompt_direnv "$white""($direnv_dir) $__fish_prompt_normal"
5959+ end
6060+4861 set -l prompt_hostname (prompt_hostname)
4962 # Color hostname magenta if we're in a container, otherwise just use it as-is
5063 if test -f /run/.containerenv # podman
···54675568 set -l prompt_os (uname)
5669 if test "$YADM_DISTRO" = nixos
5757- set prompt_os "$nix_icon "
7070+ set prompt_os "$nix_icon"
5871 else if test $prompt_os = Darwin
5959- set prompt_os " "
6060- else if test $prompt_os = Linux # Maybe could special-case nixos here?
6161- set prompt_os " "
7272+ set prompt_os ""
7373+ else if test $prompt_os = Linux
7474+ set prompt_os ""
6275 else
6376 set prompt_os ""
6477 end
7878+ if test "$YADM_OS" = WSL
7979+ set prompt_os "$prompt_os "
8080+ end
65816682 set prompt_os "$white$prompt_os$__fish_prompt_normal"
67836884 set first_line (
6969- echo -n -s "$prompt_os" "$__fish_prompt_pyenv" "$__fish_prompt_nix" \
8585+ echo -n -s "$prompt_os" \
8686+ "$__fish_prompt_pyenv" "$__fish_prompt_nix" "$__fish_prompt_direnv" \
7087 '[' "$USER" '@' "$prompt_hostname" ']' \
7188 ' ' "$__fish_prompt_cwd" (prompt_pwd)
7289 )
···101118102119 set -g __fish_git_prompt_shorten_branch_len $remaining_char_count
103120104104- set -l vcs_prompt (__fish_vcs_prompt)
121121+122122+ set -l vcs_prompt
123123+ if test "$YADM_OS" = WSL; and string match -q --regex '^/mnt/[a-z]/' $PWD
124124+ if git rev-parse --show-toplevel &>/dev/null
125125+ set vcs_prompt (set_color bryellow)" (-WSL-)"(set_color normal)
126126+ end
127127+ else
128128+ set vcs_prompt (__fish_vcs_prompt)
129129+ end
105130 if string length -q -- $vcs_prompt
106131 set first_line "$first_line""$vcs_prompt"
107132 end
+11
.config/fish/functions/fork.fish
···11+function fork
22+ if test "$YADM_OS" = WSL
33+ set -l args
44+ for arg in $argv
55+ set -a args (wslpath -w -- $arg)
66+ end
77+ command fork.exe $args
88+ else
99+ command fork $argv
1010+ end
1111+end
+16-4
.config/fish/functions/upfind.fish
···11function upfind --description 'Finds a file with the given name, upwards'
22+ set -l usage "Usage:
33+ upfind [-a|--all] [-d DIR|--from=DIR] FILE"
44+55+ argparse --min-args=1 a/all d/from= -- $argv
66+ or begin
77+ echo $usage
88+ return
99+ end
1010+211 set dir $PWD
33- if set -q argv[2]
44- set dir $argv[2]
1212+ if set -q _flag_from
1313+ set dir $_flag_from
514 end
615716 test (builtin realpath --no-symlinks $dir) != /
···9181019 if test -e $dir/$argv[1]
1120 builtin realpath --no-symlinks $dir/$argv[1]
1212- else
1313- upfind $argv[1] $dir/..
2121+ if not set -ql _flag_all
2222+ return
2323+ end
1424 end
2525+2626+ upfind $argv[1] --from=$dir/..
1527end
···11+# The current version of the config schema
22+version: 1
33+# What protocol to use when performing git operations. Supported values: ssh, https
44+git_protocol: https
55+# What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment.
66+editor:
77+# When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled
88+prompt: enabled
99+# Preference for editor-based interactive prompting. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled
1010+prefer_editor_prompt: disabled
1111+# A pager program to send command output to, e.g. "less". If blank, will refer to environment. Set the value to "cat" to disable the pager.
1212+pager:
1313+# Aliases allow you to create nicknames for gh commands
1414+aliases:
1515+ co: pr checkout
1616+ cpr: pr create --web --assignee @me
1717+# The path to a unix socket through which send HTTP connections. If blank, HTTP traffic will be handled by net/http.DefaultTransport.
1818+http_unix_socket:
1919+# What web browser gh should use when opening URLs. If blank, will refer to environment.
2020+browser:
···11+22+# Override use_flake to inject a helper variable for prompts
33+# https://stackoverflow.com/a/1369211/14436105
44+eval "$(echo "orig_use_flake()"; declare -f use_flake | tail -n +2)"
55+function use_flake() {
66+ export DIRENV_USED="flake:''${1:-$(basename "$PWD")}"
77+ orig_use_flake "$@";
88+}
99+1010+# Convenience variable for generic prompt awareness
1111+export DIRENV_USED="direnv"
1212+1313+1414+# Helper to load extra flakes or nixpkgs into the environment (as if by `nix shell`).
1515+use_pkgs() {
1616+ pkgs=()
1717+ for pkg in "$@"; do
1818+ if [[ "$pkg" = *#* || "$pkg" = *:* ]]; then
1919+ pkgs+=("$pkg")
2020+ else
2121+ pkgs+=("nixpkgs#$pkg")
2222+ fi
2323+ done
2424+ direnv_load nix shell "${pkgs[@]}" --command "$direnv" dump
2525+}
+157-71
.config/home-manager/home.nix
···22, config
33, lib
44, pkgs
55-, unstable ? import <nixos-unstable> { } # backwards compat for non-flake
66-, homeDirectory ? "/home/${config.home.user}"
55+, unstable ? import <nixos-unstable> { }
66+, # backwards compat for non-flake
77+ homeDirectory ? "/home/${config.home.user}"
88+, host
79, ...
810}:
911let
···12141315 nix-homebrew = (self.inputs or { }).nix-homebrew or null;
1416 user = config.home.user or "ianchamberlain";
1717+1818+ # ugh this will be different between nixos and others won't it
1919+2020+ packpathDirs = config.programs.neovim.finalPackage.packpathDirs;
2121+ finalPackdir = (unstable.neovimUtils.packDir packpathDirs);
2222+ packdirPackage =
2323+ pkgs.runCommand "pack" { } # bash
2424+ ''
2525+ mkdir -p $out/opt/nvim/
2626+ ${lib.getExe pkgs.xorg.lndir} -silent ${finalPackdir} $out/opt/nvim/
2727+ '';
1528in
1629{
1717- imports = [
3030+ imports = self.lib.existingPaths [
1831 ./macos-defaults.nix
1932 ./default-apps.nix
3333+ ./direnv
3434+ # This is kinda janky but I guess it works...
3535+ # https://github.com/nix-community/home-manager/issues/1906
3636+ ./${if host.wsl then "" else "non-"}wsl.nix
3737+ ./${host.class}
2038 # ./firefox.nix # TODO
2139 ];
2240···5775 programs = {
5876 # Let Home Manager install and manage itself.
5977 home-manager.enable = true;
6060-6161- bat.enable = true;
7878+ bat = {
7979+ enable = true;
8080+ # Not working for whatever reason:
8181+ extraPackages = with unstable.bat-extras; [
8282+ batdiff
8383+ batman
8484+ batgrep
8585+ batwatch
8686+ ];
8787+ };
6288 fd.enable = true;
6389 fish.enable = true;
6490 git.enable = true;
6591 gpg.enable = true;
9292+ helix = {
9393+ enable = true;
9494+ package = unstable.helix;
9595+ settings = {
9696+ theme = "monokai";
9797+ };
9898+ };
6699 htop.enable = true;
67100 neovim = {
68101 enable = true;
69102 # https://github.com/NixOS/nixpkgs/issues/137829
70103 package = unstable.neovim-unwrapped;
104104+71105 plugins = [
7272- (unstable.vimPlugins.nvim-treesitter.withPlugins (p: with p; [
7373- bash
7474- javascript
7575- nix
7676- python
7777- vimdoc
7878- xml
7979- ]))
106106+ (unstable.vimPlugins.nvim-treesitter.withPlugins (
107107+ # Include default bundled languages as well here:
108108+ # https://github.com/nvim-treesitter/nvim-treesitter/issues/3092
109109+ plugins: with plugins; [
110110+ bash
111111+ c
112112+ comment
113113+ cpp
114114+ css
115115+ csv
116116+ diff
117117+ dockerfile
118118+ fish
119119+ go
120120+ html
121121+ javascript
122122+ json
123123+ lua
124124+ markdown
125125+ nix
126126+ printf
127127+ python
128128+ query
129129+ regex
130130+ rust
131131+ toml
132132+ typescript
133133+ vim
134134+ vimdoc
135135+ xml
136136+ ]
137137+ ))
138138+ ];
139139+ extraWrapperArgs = [
140140+ "--add-flags"
141141+ # Move my configs to the front of path in order to pick up treesitter queries etc.
142142+ # before the vim-pack-dir ones provided by nixpkgs / withPlugins
143143+ (lib.escapeShellArgs [
144144+ # TODO: maybe these should use config.xdg.configHome
145145+ "--cmd"
146146+ "set runtimepath-=~/.config/nvim"
147147+ "--cmd"
148148+ "set runtimepath^=~/.config/nvim"
149149+ "--cmd"
150150+ "set packpath-=~/.config/nvim"
151151+ "--cmd"
152152+ "set packpath^=~/.config/nvim"
153153+ ])
80154 ];
81155 };
82156 ripgrep.enable = true;
···103177104178 # TODO: this should probably be handled by nix-homebrew and/or `brew completions link`
105179 xdg.dataFile = lib.mkIf stdenv.isDarwin {
106106- "fish/vendor_completions.d/brew.fish".source = "${nix-homebrew.inputs.brew-src}/completions/fish/brew.fish";
180180+ "fish/vendor_completions.d/brew.fish".source =
181181+ "${nix-homebrew.inputs.brew-src}/completions/fish/brew.fish";
107182 };
108183109184 services = {
···116191 # };
117192118193 # syncthing.enable = true;
119119-120194 # For commit signing, git-crypt, etc.
121195 gpg-agent = {
122196 # https://github.com/nix-community/home-manager/issues/3864
123197 # TODO: it would be nice to setup gpg-agent.conf on macOS properly
124198 # during activation... Maybe nix-darwin has something?
125199 enable = stdenv.isLinux;
126126-127200 defaultCacheTtl = 432000; # 5 days
128201 maxCacheTtl = 432000;
129129- pinentryPackage = pkgs.pinentry-curses;
202202+ pinentryPackage = lib.mkIf (!host.wsl) pkgs.pinentry-curses;
130203 };
131204 };
132205133206 # See services.gpg-agent - manually set up conf file on macos instead
134134- home.file.".gnupg/gpg-agent.conf" = lib.mkIf stdenv.isDarwin {
135135- text = ''
136136- # Use nix-packaged pinentry-mac
137137- pinentry-program ${pkgs.pinentry_mac}/bin/pinentry-mac
138138- # Set TTL to 5 days for GPG passphrase prompt
139139- default-cache-ttl 432000
140140- max-cache-ttl 432000
141141- '';
207207+ home.file = {
208208+ ".gnupg/gpg-agent.conf" = lib.mkIf stdenv.isDarwin {
209209+ text = ''
210210+ # Use nix-packaged pinentry-mac
211211+ pinentry-program ${pkgs.pinentry_mac}/bin/pinentry-mac
212212+ # Set TTL to 5 days for GPG passphrase prompt
213213+ default-cache-ttl 432000
214214+ max-cache-ttl 432000
215215+ '';
216216+ };
142217 };
143218144144- home.packages = with pkgs; [
145145- buildifier
146146- clang-tools
147147- docker
148148- docker-compose
149149- docker-credential-helpers
150150- file
151151- gh
152152- git-crypt
153153- git-lfs
154154- go
155155- home-manager # omitted when nix-darwin module is in use, even with programs.home-manager enabled
156156- ncurses # Newer version including tset/reset, can understand tmux terminfo etc.
157157- nil
158158- nixpkgs-fmt
159159- openssh
160160- python3
161161- rustup
162162- shellcheck
163163- thefuck
164164- tmux
165165- tree
166166- unstable.lnav
167167- unstable.nixd
168168- unzip
169169- watch
170170- yadm
219219+ home.packages =
220220+ with pkgs;
221221+ [
222222+ buildifier
223223+ # unstable.bacon # also available as a flake if I need bleeding-edge
224224+ clang-tools
225225+ comby
226226+ difftastic
227227+ docker
228228+ docker-compose
229229+ docker-credential-helpers
230230+ file
231231+ packdirPackage # so I can reference it for Lua-LSP etc.
232232+ gh
233233+ git-crypt
234234+ git-lfs
235235+ go
236236+ home-manager # omitted when nix-darwin module is in use, even with programs.home-manager enabled
237237+ mold
238238+ ncurses # Newer version including tset/reset, can understand tmux terminfo etc.
239239+ nil
240240+ nixpkgs-fmt
241241+ unstable.nixfmt-rfc-style
242242+ openssh
243243+ python3
244244+ rustup
245245+ shellcheck
246246+ thefuck
247247+ tmux
248248+ tree
249249+ unstable.lnav
250250+ unstable.nixd
251251+ unzip
252252+ watch
253253+ yadm
171254172172- # Fish completions + path setup stuff, needed since I'm not letting
173173- # home-manager do all the shell setup for me. Most notably, this creates
174174- # ~/.nix-profile/etc/profile.d/nix.fish - don't remove without a replacement!
175175- #
176176- # This may cause trouble on nixOS but I can't remember why...
177177- config.nix.package
178178- ]
179179- ++ lib.optionals stdenv.isDarwin [
180180- # Might also consider pinentry-touchid
181181- pinentry_mac
182182- swiftdefaultapps
183183- colima
184184- ]
185185- ++ lib.optionals stdenv.isLinux [
186186- pinentry-curses
187187- ];
255255+ # Fish completions + path setup stuff, needed since I'm not letting
256256+ # home-manager do all the shell setup for me. Most notably, this creates
257257+ # ~/.nix-profile/etc/profile.d/nix.fish - don't remove without a replacement!
258258+ #
259259+ # This may cause trouble on nixOS but I can't remember why...
260260+ config.nix.package
261261+ ]
262262+ ++ lib.optionals stdenv.isDarwin [
263263+ # Might also consider pinentry-touchid
264264+ pinentry_mac
265265+ swiftdefaultapps
266266+ colima
267267+ ]
268268+ ++ lib.optionals stdenv.isLinux [
269269+ pinentry-curses
270270+ ]
271271+ ++ lib.optionals host.wsl [
272272+ podman # use podman --remote to access host WSL podman instance
273273+ ];
188274189189- home.sessionVariables = lib.mkIf
190190- (!stdenv.isDarwin)
191191- (self.lib.sslCertEnv "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt");
275275+ home.sessionVariables = lib.mkIf (!stdenv.isDarwin) (
276276+ self.lib.sslCertEnv "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
277277+ );
192278193279 home.stateVersion = "20.09";
194280}
+30
.config/home-manager/wsl/default.nix
···11+{ pkgs, lib, ... }:
22+let
33+ pinentry-injector = pkgs.callPackage ./wsl/pinentry-injector/package.nix { };
44+55+ # Request pinentry via Git-bash's GPG instead of pinentry-curses
66+ pinentry-wrapper = pkgs.writeShellApplication {
77+ name = "pinentry-win";
88+ # TODO: PR these as inputs for nixpkgs#wslu itself?
99+ runtimeInputs = with pkgs; [ wslu coreutils gnused pinentry-injector ];
1010+ # TODO: if I write a real program to intercept stdin/stdout I can inject
1111+ # a SETTITLE command using the key name for AutoType to work nicer. Ideally
1212+ # cross-platform enough to work on native windows too
1313+ text = /*bash*/ ''
1414+ # Add wslpath to PATH (for wslu to work properly)
1515+ export PATH=/bin:$PATH
1616+ # Gpg4Win's pinentry-qt seems better behaved than plain pinentry from Git for Windows
1717+ real_pinentry="$(wslpath "$(wslvar -s USERPROFILE)")/scoop/apps/gpg4win/current/Gpg4win/bin/pinentry.exe"
1818+ exec "${lib.getExe pinentry-injector}" "$real_pinentry" "$@"
1919+ '';
2020+ };
2121+in
2222+{
2323+ services.gpg-agent.pinentryPackage = pinentry-wrapper;
2424+2525+ home.file.".local/bin/xdg-open".source = lib.getExe' pkgs.wslu "wslview";
2626+ home.packages = with pkgs; [
2727+ wslu
2828+ pinentry-wrapper
2929+ ];
3030+}
···11+// A simple app to wrap `pinentry`, intercepting the description while looking
22+// for an email address; if found it will be injected into the real pinentry's
33+// title.
44+//
55+// This is probably insecure for some reason or other so use with care.
66+77+package main
88+99+import (
1010+ "bufio"
1111+ "errors"
1212+ "fmt"
1313+ "io"
1414+ "os"
1515+ "os/exec"
1616+ "regexp"
1717+)
1818+1919+func main() {
2020+ err := run(os.Args[1], os.Args[1:]...)
2121+2222+ if err != nil {
2323+ var exitErr *exec.ExitError
2424+ if errors.As(err, &exitErr) {
2525+ os.Exit(exitErr.ExitCode())
2626+ } else {
2727+ os.Exit(1)
2828+ }
2929+ }
3030+}
3131+3232+var emailRegex = regexp.MustCompile(`(?:%22|")(?P<name>.+?) <(?P<email>.+?)>(?:%22|")`)
3333+3434+const emailAddressIndex = 2
3535+3636+func run(realPinentry string, pinentryArgs ...string) (err error) {
3737+ pinentry := exec.Command(realPinentry, pinentryArgs...)
3838+3939+ pinentryStdin, err := pinentry.StdinPipe()
4040+ if err != nil {
4141+ return err
4242+ }
4343+ defer pinentryStdin.Close()
4444+4545+ pinentryStdout, err := pinentry.StdoutPipe()
4646+ if err != nil {
4747+ return err
4848+ }
4949+ defer pinentryStdout.Close()
5050+5151+ if err = pinentry.Start(); err != nil {
5252+ return err
5353+ }
5454+ defer func() {
5555+ err = errors.Join(err, pinentry.Wait())
5656+ }()
5757+5858+ stdinScanner := bufio.NewScanner(os.Stdin)
5959+ myStdin := make(chan string)
6060+ go func() {
6161+ for stdinScanner.Scan() {
6262+ myStdin <- stdinScanner.Text()
6363+ }
6464+ close(myStdin)
6565+ }()
6666+6767+ stdoutScanner := bufio.NewScanner(pinentryStdout)
6868+ pinentryOut := make(chan string)
6969+ go func() {
7070+ for stdoutScanner.Scan() {
7171+ pinentryOut <- stdoutScanner.Text()
7272+ }
7373+ close(pinentryOut)
7474+ }()
7575+7676+loop:
7777+ for {
7878+ fmt.Fprintln(os.Stderr, "waiting for input...")
7979+ select {
8080+ case inLine, ok := <-myStdin:
8181+ if !ok {
8282+ // EOF from client, pass it along by closing the pipe
8383+ _ = pinentryStdin.Close()
8484+ break loop
8585+ }
8686+8787+ fmt.Fprintf(os.Stderr, "Got input line: %q\n", inLine)
8888+ if email := emailRegex.FindStringSubmatch(inLine); email != nil {
8989+ fmt.Fprintln(os.Stderr, "matched mail regex")
9090+ io.WriteString(pinentryStdin, fmt.Sprintf("SETTITLE pinentry: <%s>\n", email[emailAddressIndex]))
9191+ response := <-pinentryOut
9292+ if response != "OK" {
9393+ os.Stderr.WriteString("failed to settitle")
9494+ break
9595+ }
9696+ }
9797+ io.WriteString(pinentryStdin, inLine+"\n")
9898+9999+ case outLine, ok := <-pinentryOut:
100100+ if !ok {
101101+ break loop
102102+ }
103103+ fmt.Fprintf(os.Stderr, "Got output line: %q\n", outLine)
104104+ fmt.Println(outLine)
105105+ }
106106+107107+ }
108108+ err = errors.Join(stdinScanner.Err(), stdoutScanner.Err())
109109+ if err != nil {
110110+ fmt.Fprintf(os.Stderr, "Done: %s\n", err)
111111+ }
112112+113113+ return err
114114+}
+54-35
.config/nix-darwin/configuration.nix
···11-{ self, lib, config, pkgs, unstable, host, ... }:
11+{
22+ self,
33+ lib,
44+ config,
55+ pkgs,
66+ unstable,
77+ host,
88+ ...
99+}:
210let
311 # https://discourse.nixos.org/t/ssl-ca-cert-error-on-macos/31171/6
412 # https://github.com/NixOS/nixpkgs/issues/66716
···3240 ];
33413442 shells = [ pkgs.fish ];
3535- loginShell = "${pkgs.fish}/bin/fish";
4343+ loginShell = "${lib.getExe pkgs.fish}";
36443737- etc = let homeDir = config.users.users.${host.user}.home; in {
3838- # Symlink to dotfiles flake for easier activation
3939- "nix-darwin/flake.nix".source = "${homeDir}/.config/flake.nix";
4040- };
4545+ etc =
4646+ let
4747+ homeDir = config.users.users.${host.user}.home;
4848+ in
4949+ {
5050+ # Symlink to dotfiles flake for easier activation
5151+ "nix-darwin/flake.nix".source = "${homeDir}/.config/flake.nix";
5252+ };
41534254 variables = mkIfWork systemCABundleEnv;
4355 };
···47594860 nix.package = unstable.lix;
4961 # Necessary for using flakes on this system.
5050- nix.settings.experimental-features = [ "nix-command" "flakes" ];
6262+ nix.settings.experimental-features = [
6363+ "nix-command"
6464+ "flakes"
6565+ ];
51665267 # Seems to be necessary on work laptop probably due to some MITM certs or something...
5368 # Needs plumbing into launchd or /etc/profile I think, not working just yet...
···7691 remapCapsLockToEscape = true;
77927893 /*
7979- # https://developer.apple.com/library/content/technotes/tn2450/_index.html
8080- userKeyMapping = let hex = lib.fromHexString; in [
8181- # TODO: what is this mapping from?? Need to figure out what other ones
8282- # from currentHost defaults I care about, if any
8383- {
8484- HIDKeyboardModifierMappingSrc = hex "0xFF0100000003";
8585- HIDKeyboardModifierMappingDst = hex "0x00FF00000003";
8686- }
8787- ];
8888- # */
9494+ # https://developer.apple.com/library/content/technotes/tn2450/_index.html
9595+ userKeyMapping = let hex = lib.fromHexString; in [
9696+ # TODO: what is this mapping from?? Need to figure out what other ones
9797+ # from currentHost defaults I care about, if any
9898+ {
9999+ HIDKeyboardModifierMappingSrc = hex "0xFF0100000003";
100100+ HIDKeyboardModifierMappingDst = hex "0x00FF00000003";
101101+ }
102102+ ];
103103+ #
104104+ */
89105 };
9010691107 # Set up apps after homebrew, so that everything we try to add should be installed
···105121 "${appdir}/Stretchly.app"
106122 "${appdir}/Syncthing.app"
107123 ];
108108- appEntries = map
109109- (app: { path = app; hidden = true; })
110110- apps;
124124+ appEntries = map (app: {
125125+ path = app;
126126+ hidden = true;
127127+ }) apps;
111128112129 # This somehow seems to be the only way to add apps to "Open at Login" that doesn't
113130 # involve launchd, and there doesn't seem to be any `defaults` for it anymore
114114- updateEntries = /* javascript */ ''
115115- "use strict";
116116- (() => {
117117- const se = Application("System Events");
131131+ updateEntries = # javascript
132132+ ''
133133+ "use strict";
134134+ (() => {
135135+ const se = Application("System Events");
118136119119- // https://stackoverflow.com/a/48026729
120120- while (se.loginItems.length > 0) {
121121- se.loginItems[0].delete();
122122- }
137137+ // https://stackoverflow.com/a/48026729
138138+ while (se.loginItems.length > 0) {
139139+ se.loginItems[0].delete();
140140+ }
123141124124- // This interface is strange... https://bru6.de/jxa/basics/working-with-objects/
125125- for (const app of ${builtins.toJSON appEntries}) {
126126- se.loginItems.push(se.LoginItem(app));
127127- }
128128- })()
129129- '';
142142+ // This interface is strange... https://bru6.de/jxa/basics/working-with-objects/
143143+ for (const app of ${builtins.toJSON appEntries}) {
144144+ se.loginItems.push(se.LoginItem(app));
145145+ }
146146+ })()
147147+ '';
130148 in
131131- /* bash */ ''
149149+ # bash
150150+ ''
132151 /usr/bin/osascript -l JavaScript -e ${lib.escapeShellArg updateEntries}
133152 '';
134153 };
+33-22
.config/nix/lib.nix
···33# appropriate `pkgs`, but for now `self.lib` is good enough
44{ self, lib, ... }:
55{
66- /** Return the given value if non-null, otherwise the given `default` */
77- unwrapOr = default: v:
88- if v == null then default else v;
66+ /**
77+ Return the given value if non-null, otherwise the given `default`
88+ */
99+ unwrapOr = default: v: if v == null then default else v;
9101010- /** Filter a list of paths to include only those that actually exist */
1111+ /**
1212+ Filter a list of paths to include only those that actually exist
1313+ */
1114 existingPaths = builtins.filter builtins.pathExists;
12151313- /** Enable "escape sequences" in a string by (ab)using the builtin Nix JSON parser.
1414- For readability / sanity, this should probably only ever be used with a
1515- single-quoted '' literals for backslashes to work as expected.
1616- <https://github.com/NixOS/nix/issues/10082>
1717- */
1818- unescape = s:
1919- let escaped = builtins.replaceStrings [ "\"" ] [ "\\\"" ] s;
2020- in builtins.fromJSON ''"${escaped}"'';
1616+ /**
1717+ Enable "escape sequences" in a string by (ab)using the builtin Nix JSON parser.
1818+ For readability / sanity, this should probably only ever be used with a
1919+ single-quoted '' literals for backslashes to work as expected.
2020+ <https://github.com/NixOS/nix/issues/10082>
2121+ */
2222+ unescape =
2323+ s:
2424+ let
2525+ escaped = builtins.replaceStrings [ "\"" ] [ "\\\"" ] s;
2626+ in
2727+ builtins.fromJSON ''"${escaped}"'';
21282222- /** com.apple.dock helpers */
2929+ /**
3030+ com.apple.dock helpers
3131+ */
2332 dock = with self.lib.dock; {
2433 path-entry = path: {
2534 tile-data = {
···3039 };
3140 };
32413333- folder = path: lib.recursiveUpdate (path-entry path) {
3434- tile-data = {
3535- # Show as folder icon instead of stack etc.
3636- displayas = 1;
3737- # Use default appearance for contents, set 2 to force grid here
3838- showas = 0;
4242+ folder =
4343+ path:
4444+ lib.recursiveUpdate (path-entry path) {
4545+ tile-data = {
4646+ # Show as folder icon instead of stack etc.
4747+ displayas = 1;
4848+ # Use default appearance for contents, set 2 to force grid here
4949+ showas = 0;
5050+ };
5151+ tile-type = "directory-tile";
3952 };
4040- tile-type = "directory-tile";
4141- };
42534354 app-in-dir = dir: appName: path-entry "${dir}/${appName}.app";
4455 system-app = app-in-dir "/System/Applications";
···55665667 Not which are needed / relevant all the time, but I've seen a bunch
5768 of various resources refer to one or multiple of these...
5858- */
6969+ */
5970 sslCertEnv = caBundle: {
6071 NIX_SSL_CERT_FILE = caBundle;
6172 SSL_CERT_FILE = caBundle;
+82-8
.config/nixos/configuration.nix
···11-{ config, lib, pkgs, host, ... }:
11+{
22+ config,
33+ lib,
44+ pkgs,
55+ unstable,
66+ host,
77+ lix-module,
88+ ...
99+}:
210{
311 # TODO: when converting prismo, will probably import ./prismo.nix or something
412 imports = [
55- ./wsl.nix
1313+ ./wsl
614 ];
71588- nix.settings.experimental-features = [ "nix-command" "flakes" ];
99- nix.package = pkgs.lix;
1616+ nix = {
1717+ settings = {
1818+ experimental-features = [
1919+ "nix-command"
2020+ "flakes"
2121+ ];
2222+ # Disable the global flake registry; nixpkgs came free with your cfg!
2323+ # This might make more sense in home.nix to work on darwin etc too
2424+ flake-registry = null;
2525+ };
2626+ package = unstable.lix;
2727+2828+ # TODO: figure out a way to add registry entries so I can do e.g.
2929+ # `nix run pkgs#htop` and get my custom htop instead of upstream
3030+ registry.unstable.to = {
3131+ type = "github";
3232+ owner = "NixOS";
3333+ repo = "nixpkgs";
3434+ ref = "nixos-unstable";
3535+ };
3636+ };
10371138 time.timeZone = "America/New_York";
12394040+ documentation.dev.enable = true;
1341 environment = {
1442 systemPackages = with pkgs; [
1543 git
···1846 wget
1947 ];
20482121- etc = let homeDir = config.users.users.${host.user}.home; in {
2222- # Symlink to dotfiles flake for easier activation
2323- "nixos/flake.nix".source = "${homeDir}/.config/flake.nix";
4949+ etc =
5050+ let
5151+ homeDir = config.users.users.${host.user}.home;
5252+ in
5353+ {
5454+ # Symlink to dotfiles flake for easier activation
5555+ "nixos/flake.nix".source = "${homeDir}/.config/flake.nix";
5656+ };
5757+5858+ # Override the default aliases, I brought my own
5959+ shellAliases = {
6060+ ls = null;
6161+ ll = null;
6262+ l = null;
2463 };
2564 };
26652727- programs.fish.enable = true;
6666+ # Based on /bin/sh:
6767+ # https://github.com/NixOS/nixpkgs/blob/8261f6e94510101738ab45f0b877f2993c7fb069/nixos/modules/config/shells-environment.nix#L213
6868+ system.activationScripts.binbash =
6969+ let
7070+ bash = lib.getExe config.system.build.binsh;
7171+ in
7272+ lib.stringAfter [ "stdio" ]
7373+ # bash
7474+ ''
7575+ mkdir -m 0755 -p /bin
7676+ ln -sfn "${bash}" /bin/.bash.tmp
7777+ mv /bin/.bash.tmp /bin/bash # atomically replace /bin/bash
7878+ '';
7979+8080+ systemd.coredump = {
8181+ enable = true;
8282+ # Explicit defaults:
8383+ extraConfig = ''
8484+ Storage=external
8585+ Compress=yes
8686+ # On 32-bit, the default is 1G instead of 32G.
8787+ ProcessSizeMax=32G
8888+ ExternalSizeMax=32G
8989+ JournalSizeMax=767M
9090+ MaxUse=
9191+ KeepFree=
9292+ EnterNamespace=no
9393+ '';
9494+ };
9595+9696+ programs = {
9797+ fish = {
9898+ enable = true;
9999+ useBabelfish = true;
100100+ };
101101+ };
2810229103 users.users.${host.user} = {
30104 isNormalUser = true;
···11+if not vim.g.vscode then
22+ return
33+end
44+55+-- Disable regular syntax highlights, we only care about treesitter
66+vim.cmd("syntax off")
77+88+-- Languages without vscode highlighting:
99+local enabled_langs = { "vimdoc", "query" }
1010+-- These languages have a vscode grammar/LSP, but not injection support; we can
1111+-- use treesitter's injection to supplement syntax highlighting (nice!)
1212+local injected_langs = VSCODE_INJECTED_LANGS
1313+1414+local injection_disabled = { "markdown" }
1515+1616+-- Wrap this whole thing in a pcall in case treesitter isn't installed
1717+local success, error = pcall(function()
1818+ local ts_parsers = require("nvim-treesitter.parsers")
1919+2020+ for _, lang in pairs(ts_parsers.available_parsers()) do
2121+ if ts_parsers.has_parser(lang) and not vim.list_contains(enabled_langs, lang) then
2222+ -- Disable everything but injections + nvim-surround
2323+ for _, query in ipairs({ "locals", "folds", "indents" }) do
2424+ vim.treesitter.query.set(lang, query, "")
2525+ end
2626+2727+ -- Keep highlights active for injected langs, that's the whole point
2828+ if not vim.list_contains(injected_langs, lang) then
2929+ vim.treesitter.query.set(lang, "highlights", "")
3030+ end
3131+3232+ -- would love to do something like this but there doesn't seem to be
3333+ -- a way to go back to parsed query from query info...
3434+ --[[
3535+ local q = vim.treesitter.query.get(lang, "highlights")
3636+ for _, pattern in pairs(q.info.patterns) do
3737+ table.insert(pattern, { "injected?" })
3838+ end
3939+ ]]
4040+4141+ if vim.list_contains(injection_disabled, lang) then
4242+ vim.treesitter.query.set(lang, "injections", "")
4343+ end
4444+ end
4545+ end
4646+4747+ -- Completely deregister everything vscode-neovim does for highlights
4848+ vim.api.nvim_create_augroup("vscode.treesitter", { clear = true })
4949+ local hl_group = vim.api.nvim_create_augroup("vscode.highlight", { clear = true })
5050+5151+ local function fixup_highlights()
5252+ -- And then reimplement a subset of it (i.e. just global highlights)
5353+ -- https://github.com/vscode-neovim/vscode-neovim/blob/master/runtime/lua/vscode/highlight.lua#L25
5454+ -- Probably this could be upstreamed as a simple config option or something...
5555+ for name, value in pairs({
5656+ ColorColumn = {},
5757+ CursorColumn = {},
5858+ CursorLine = {},
5959+ CursorLineNr = {},
6060+ Debug = {},
6161+ EndOfBuffer = {},
6262+ FoldColumn = {},
6363+ Folded = {},
6464+ LineNr = {},
6565+ LineNrAbove = {},
6666+ LineNrBelow = {},
6767+ MatchParen = {},
6868+ MsgArea = {},
6969+ MsgSeparator = {},
7070+ NonText = {},
7171+ Normal = {},
7272+ NormalFloat = {},
7373+ NormalNC = {},
7474+ NormalSB = {},
7575+ Question = {},
7676+ QuickFixLine = {},
7777+ Quote = {},
7878+ Sign = {},
7979+ SignColumn = {},
8080+ Substitute = {},
8181+ Visual = {},
8282+ VisualNC = {},
8383+ VisualNOS = {},
8484+ Whitespace = {},
8585+8686+ -- make cursor visible for plugins that use fake cursor
8787+ Cursor = { reverse = true },
8888+8989+ ["@markup.link"] = {},
9090+ ["@markup.link.label"] = {},
9191+ ["@markup.link.url"] = {},
9292+9393+ ["@markup.raw.markdown_inline"] = {
9494+ fg = "#FD971F",
9595+ bold = false,
9696+ italic = false,
9797+ },
9898+ ["@markup.strong"] = { fg = "#66D9EF", bold = true },
9999+ ["@markup.italic"] = { fg = "#66D9EF", italic = true },
100100+ }) do
101101+ if vim.tbl_isempty(value) then
102102+ vim.api.nvim_set_hl(0, name, { link = "VSCodeNone", force = true })
103103+ else
104104+ vim.api.nvim_set_hl(0, name, value)
105105+ end
106106+ end
107107+ end
108108+109109+ vim.api.nvim_create_autocmd({ "ColorScheme" }, { group = hl_group, callback = fixup_highlights })
110110+111111+ vim.api.nvim_create_autocmd({
112112+ "BufEnter",
113113+ "BufLeave",
114114+ "WinEnter",
115115+ "WinLeave",
116116+ "BufWinEnter",
117117+ "BufWinLeave",
118118+ "WinScrolled",
119119+ "FocusGained",
120120+ "VimEnter",
121121+ "UIEnter",
122122+ }, {
123123+ group = hl_group,
124124+ callback = function()
125125+ -- There are still some oddities with scrolling etc. for redraw,
126126+ -- haven't quite figured out the details yet...
127127+ vim.cmd("mode")
128128+ vim.cmd("redraw!")
129129+ end,
130130+ })
131131+132132+ fixup_highlights()
133133+end)
134134+135135+if not success then
136136+ vim.print("failed to do vscode-hl setup", error)
137137+end
···2626require("nvim-surround").setup()
2727require("ns-textobject").setup()
28282929+-- Global, used in ./after/lua/vscode-custom.lua
3030+VSCODE_INJECTED_LANGS = {}
3131+3232+-- Wrap this in a pcall in case treesitter isn't installed
3333+local success, error = pcall(function()
3434+ -- langs without vscode equivalent, always enable highlights for these
3535+3636+ if vim.g.vscode then
3737+ -- TODO: I'd love to figure out how to disable these at the top-level and only enable for injections
3838+ VSCODE_INJECTED_LANGS = { "fish", "bash", "javascript", "vim", "regex", "markdown_inline", "markdown", "lua", "json" }
3939+ end
4040+4141+ vim.treesitter.query.add_predicate("vscode?", function()
4242+ return vim.g.vscode and true or false
4343+ end, { force = true, all = true })
4444+4545+ vim.treesitter.query.add_predicate("injected?", function(_match, _pattern, buf, pred)
4646+ if type(buf) ~= "number" then
4747+ return
4848+ end
4949+5050+ local parser_ft = vim.filetype.match({ buf = buf })
5151+ local buf_ft = vim.filetype.match({ buf = vim.fn.bufnr() })
5252+5353+ return buf_ft ~= parser_ft
5454+ end, { force = true, all = true })
5555+5656+ require("nvim-treesitter.configs").setup({
5757+ highlight = {
5858+ enable = true,
5959+ -- These can be disabled at the top level like this, but they're still allowed
6060+ -- as injected languages so e.g. vim.cmd and nix injections work, without
6161+ -- taking over highlights in vscode
6262+ disable = VSCODE_INJECTED_LANGS,
6363+ },
6464+ })
6565+end)
6666+6767+if not success then
6868+ vim.print("Failed to pcall hl setup!", error)
6969+end
7070+2971-- TODO: convert remainder of this to proper Lua config
30723173-- Wrap this in a pcall in case treesitter isn't installed
···60102if not vim.g.vscode then
61103 -- Default to dark mode if unset
62104 vim.opt.background = os.getenv("COLOR_THEME") or "dark"
105105+106106+ if vim.fn.has("wsl") ~= 0 then
107107+ vim.g.clipboard = {
108108+ name = "WslClipboard",
109109+ copy = {
110110+ ["+"] = "clip.exe",
111111+ ["*"] = "clip.exe",
112112+ },
113113+ paste = {
114114+ -- yeesh, is this really the only way to deal with this? See :h clipboard-wsl
115115+ -- fish_clipboard_paste looks like it's doing basically the same thing too
116116+ ["+"] = 'powershell.exe -c [Console]::Out.Write($(Get-Clipboard -Raw).tostring().replace("`r", ""))',
117117+ ["*"] = 'powershell.exe -c [Console]::Out.Write($(Get-Clipboard -Raw).tostring().replace("`r", ""))',
118118+ },
119119+ cache_enabled = false,
120120+ }
121121+ end
6312264123 -- TODO: https://github.com/akinsho/git-conflict.nvim
65124else
···7012971130 local group = vim.api.nvim_create_augroup("vscode-custom", {})
721317373- -- https://github.com/vscode-neovim/vscode-neovim/issues/1718
7474- vim.api.nvim_create_autocmd({ "VimEnter", "ModeChanged" }, {
7575- pattern = "*",
132132+ -- rust-analyzer commands doesn't play super nice with neovim join/match brace; this autocmd
133133+ -- setups up bindings to use the builtin motion commands in operator-pending mode
134134+ vim.api.nvim_create_autocmd({ "FileType" }, {
135135+ pattern = { "*.rs" },
76136 group = group,
7777- callback = function(args)
7878- vscode.call("setContext", {
7979- args = { "neovim.fullMode", vim.fn.mode(1) },
8080- })
137137+ callback = function()
138138+ vim.keymap.set({ "n", "v" }, "%", function()
139139+ if vim.fn.state("o") ~= "" then
140140+ vscode.action("rust-analyzer.matchingBrace")
141141+ return ""
142142+ end
143143+144144+ return "%"
145145+ end, { silent = true, remap = true, expr = true })
146146+147147+ vim.keymap.set({ "n", "v" }, "J", function()
148148+ if vim.fn.state("o") ~= "" then
149149+ vscode.action("rust-analyzer.joinLines")
150150+ return ""
151151+ end
152152+153153+ return "J"
154154+ end, { silent = true, remap = true, expr = true })
81155 end,
82156 })
8315784158 -- https://github.com/vscode-neovim/vscode-neovim/issues/1718#issuecomment-2078380657
8585- vim.keymap.set("n", "r", function()
8686- vscode.call("setContext", {
8787- args = { "neovim.fullMode", vim.fn.mode(1) .. "r" },
8888- })
8989-9090- vim.api.nvim_feedkeys("r", "n", true)
9191- end)
9215993160 -- Fix comment handling for AHK
94161 vim.api.nvim_create_autocmd({ "BufEnter" }, {
···135202136203 vim.cmd([[
137204 xnoremap <silent> <Esc> :<C-u>call VSCodeNotify('closeFindWidget')<CR>
205205+138206 nnoremap <silent> <Esc> :<C-u>call VSCodeNotify('closeFindWidget')<CR>
139207140208 " Disable airline by pretending it's already loaded
···161229162230 nmap <D-a> ggVG
163231164164- " Move cursor to end of line when making visual selection so % works as expected
165165- nmap V V$
166166-167232 " Remap for append/insert with multi-cursor to avoid extra keystroke
168233 xmap <expr> a visualmode() ==# 'v' ? 'a' : 'ma'
169234 xmap <expr> A visualmode() ==# 'v' ? 'A' : 'mA'
···231296 let g:loaded_airline = 1
232297 ]])
233298end
299299+300300+-- Do this at the end so ColorScheme autocmds work:
301301+302302+---@diagnostic disable-next-line: missing-fields
303303+require("monokai-nightasty").setup({
304304+ on_highlights = function(highlights, colors)
305305+ -- It seems like most syntaxes just use String for quotes, but
306306+ -- for some (e.g. JSON) they are highlighted differently.
307307+ -- This just forces them back to regular String highlight
308308+ highlights.Quote = highlights.String
309309+310310+ -- More like the old vim highlighting:
311311+ highlights.gitcommitSummary, highlights.gitcommitOverflow =
312312+ highlights.gitcommitOverflow, highlights.gitcommitSummary
313313+ end,
314314+})
315315+316316+vim.cmd.colorscheme("monokai-nightasty")
···11# Prevent breaking git with a bad config when it has conflicts
22.gitconfig* merge=binary
33+**/.config/git/config* merge=binary
34**/lghub/settings.db diff=sqlite3
45**/lghub/settings.db merge=keepTheir
56*.pyz filter=lfs diff=lfs merge=lfs -text
···11+#!/usr/bin/env bash
22+33+## In lieu of a more customizable --sort=... option, this is a shortcut to replace `git branch` which
44+## sorts first by a known prefix, then by committerdate. It
55+## Output format is based on the upstream implementation:
66+## <https://github.com/git/git/blob/08bdfd453584e489d5a551aecbdcb77584e1b958/builtin/branch.c#L386>
77+88+set -euo pipefail
99+1010+# TODO: it might be nice to also support main/master as higher-ranked prefix here
1111+MY_PREFIX="ian"
1212+MINE="%(if:equals=refs/heads/${MY_PREFIX})%(refname:rstrip=-3)%(then)1%(else)0%(end)"
1313+DATE='%(committerdate:unix)' # TODO maybe also consider reverse-version-sorting by branch (i.e. ticket #)
1414+1515+TAB=$'\t'
1616+1717+# Unclear why %(color:normal) doesn't behave the same as the RGB color here, or why
1818+# this is set to some white color at all (since normal is green in my terminal settings).
1919+# There must be some magic in git's codebase that sets RGB when terminal support is detected.
2020+NORMAL_COLOR='%(color:#F8F8F2)'
2121+2222+HEAD_PREFIX='*%(color:green)'
2323+WORKTREE_PREFIX='+%(color:cyan)'
2424+WORKTREE="%(if)%(worktreepath)%(then)${WORKTREE_PREFIX}%(else) %(end)"
2525+PREFIX="${NORMAL_COLOR}%(if)%(HEAD)%(then)${HEAD_PREFIX}%(else)${WORKTREE}%(end)"
2626+2727+FORMAT='%(refname:lstrip=2)%(color:reset)%(if)%(symref)%(then) -> %(symref:short)%(end)'
2828+2929+git branch --color \
3030+ --format="${DATE}${TAB}${MINE}${TAB}${PREFIX} ${FORMAT}" |
3131+ sort -r -n -k2 -k1 | # sort by $MINE, then $DATE
3232+ cut -d"$TAB" -f3 | # trim off the sort keys
3333+ git column
+27
.local/bin/git-clean-squashed
···11+#!/usr/bin/env bash
22+33+## Clean up local branches that were squash-merged into the main branch. Ported from
44+## <https://github.com/not-an-aardvark/git-delete-squashed/blob/master/bin/git-delete-squashed.js>
55+66+set -euo pipefail
77+88+DEFAULT_BRANCH=${1:-$(git default-branch)}
99+1010+# Skip checked-out branches with worktreepath
1111+git for-each-ref refs/heads/ --format='%(if)%(worktreepath)%(then)%(else)%(refname:short)%(end)' |
1212+while read -r branch; do
1313+ [[ -z $branch || $branch = "$DEFAULT_BRANCH" ]] && continue
1414+1515+ ancestor=$(git merge-base "$DEFAULT_BRANCH" "$branch")
1616+ tree=$(git rev-parse "$branch^{tree}")
1717+1818+ commit=$(git commit-tree "$tree" -p "$ancestor" -m "squash-clean: temporary commit")
1919+ set -x
2020+ echo "$branch"
2121+ cherry_result=$(git cherry "$DEFAULT_BRANCH" "$commit")
2222+ set +x
2323+2424+ if [[ "$cherry_result" = -* ]]; then
2525+ echo git branch -D "$branch"
2626+ fi
2727+done
.local/share/emacs/autosave/.gitkeep
This is a binary file and will not be displayed.
.local/share/gdb/.gitkeep
This is a binary file and will not be displayed.
+18
.vimrc
···33set tabstop=4
44set shiftwidth=4
55set softtabstop=4
66+set shiftround " lmao where has this been all my life T_T
6778set expandtab
89set backspace=indent,eol,start
···1718set autoindent
1819filetype plugin indent on
19202121+set smartcase
2222+2023" Prevent '#' from forcing 0-indent for e.g. python + bash comments
2124" This should be used instead of smartindent
2225set cindent
2326set cinkeys-=0#
2427set indentkeys-=0#
25282929+set wildmode=longest:full,full
3030+set wildoptions+=fuzzy
3131+cnoremap <M-BS> <C-w>
3232+cnoremap <M-d> <C-d>
3333+2634if &diff
2735 set diffopt+=iwhite
2836endif
···3846" Use newer info than the macOS builtin
3947let g:infoprg = '/usr/local/bin/info'
40484949+" Common typos I make while trying to save a file. It's very unlikely i'll ever need to
5050+" name a file something like "\" or "'" and if I do I can use a space or :saveas
5151+cabbrev w\ w
5252+cabbrev w' w
5353+cabbrev w] w
5454+5555+" Don't set textwidth to 99 by default. Rustfmt does the heavy lifting anyway
5656+let g:rust_recommended_style = 0
5757+4158" filetype matching
4259augroup CustomFiletypes
4360 autocmd!
···6582augroup END
66836784" Augroups, must be before `syntax on`
8585+" TODO maybe disable this for vscode-nvim
6886augroup CustomTodo
6987 autocmd!
7088 autocmd Syntax * syntax match CustomTodo /\v<(TODO|FIXME|NOTE)/ containedin=.*Comment