diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7cc6d10..95ff444 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,4 +11,4 @@ jobs: - name: Run ShellCheck uses: ludeeus/action-shellcheck@master with: - scandir: "./bashrc.d" + scandir: "./zshrc.d" diff --git a/.gitignore b/.gitignore index 55acb54..72599a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ Brewfile.lock.json +docs/superpowers/ diff --git a/Brewfile b/Brewfile index 5e7588b..c29eaeb 100644 --- a/Brewfile +++ b/Brewfile @@ -1,12 +1,14 @@ -tap 'homebrew/cask-fonts' -brew 'bash-completion' brew 'bat' -brew 'diff-so-fancy' -brew 'exa' +brew 'eza' +brew 'fd' +brew 'fzf' brew 'gibo' +brew 'git-delta' brew 'lesspipe' -brew 'liquidprompt' -brew 'python' +brew 'mise' +brew 'ripgrep' brew 'shellcheck' -brew 'svn' +brew 'starship' +brew 'zoxide' +cask 'font-sauce-code-pro-nerd-font' cask 'font-source-code-pro' diff --git a/Makefile b/Makefile index 7c55da7..ac28dd3 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ test: shellcheck .PHONY: shellcheck shellcheck: - @shellcheck bashrc.d/* + @shellcheck --shell=bash zshrc.d/* .PHONY: install install: diff --git a/bash_logout b/bash_logout deleted file mode 100644 index 7f0d4e8..0000000 --- a/bash_logout +++ /dev/null @@ -1 +0,0 @@ -# -*- mode: sh -*- diff --git a/bash_profile b/bash_profile deleted file mode 100644 index 7246143..0000000 --- a/bash_profile +++ /dev/null @@ -1,19 +0,0 @@ -# -*- mode: sh -*- - -#FIXME This should use a Darwin-specific location (e.g., ~/Library/Preferences) -# but need to test interaction with existing configs (e.g., git). -export XDG_CONFIG_HOME=${XDG_CONFIG_HOME:=$HOME/.config} - -if [ "$(uname -s)" == "Darwin" ]; then - export XDG_CACHE_HOME=${XDG_CACHE_HOME:=$HOME/Library/Caches} - export XDG_DATA_HOME=${XDG_DATA_HOME:=$HOME/Library} -else - export XDG_CACHE_HOME=${XDG_CACHE_HOME:=$HOME/.cache} - export XDG_DATA_HOME=${XDG_DATA_HOME:=$HOME/.local/share} -fi - -if [ -f ~/.profile ]; then . ~/.profile; fi -if [ -r ~/.profile.local ]; then . ~/.profile.local; fi - -if [ -f ~/.bashrc ]; then . ~/.bashrc; fi -if [ -r ~/.bashrc.local ]; then . ~/.bashrc.local; fi diff --git a/bashrc b/bashrc deleted file mode 100644 index 88a8ef9..0000000 --- a/bashrc +++ /dev/null @@ -1,73 +0,0 @@ -# -*- mode: sh -*- - -# http://www.turnkeylinux.org/blog/generic-shell-hooks -# -run_scripts() -{ - for script in $1/*; do - - # skip non-executable snippets - [ -x "$script" ] || continue - - # execute $script in the context of the current shell - . $script - done -} - -export BROWSER='open' -export CLICOLOR='1' - -export PAGER='less' -export LESS='eiMRsXx4' -export LESSHISTFILE=- - -command -v lesspipe.sh >/dev/null 2>&1 && { - export LESSOPEN="|lesspipe.sh %s" -} - -alias ..='cd ..' -alias cd..='cd ..' -alias cp='cp -i' -alias ha='history -a' -alias hn='history -n' -alias ll='ls -al' -alias md='mkdir -p' -alias mv='mv -i' -alias pbclean='pbpaste | pbcopy' -alias po='popd' -alias pu='pushd' - -# Always enable colored `grep` output -alias grep='grep --color=auto ' - -# Intuitive map function -# For example, to list all directories that contain a certain file: -# find . -name .gitattributes | map dirname -alias map='xargs -n1' - -set -o ignoreeof -set -o noclobber - -shopt -s cdspell - -# Use conventional history management in the absence of Apple Terminal's resume support -if ! [ -n "$TERM_SESSION_ID" ]; then - shopt -s histappend -fi - -cd() { - builtin cd "$1" - pwd -} - -run_scripts ~/.bashrc.d - -if [ -f /usr/local/share/liquidprompt ]; then - . /usr/local/share/liquidprompt -elif [ -f "${HOMEBREW_PREFIX}/share/liquidprompt" ]; then - . "${HOMEBREW_PREFIX}/share/liquidprompt" -fi - -GPG_TTY=$(tty) -export GPG_TTY - diff --git a/bashrc.d/aws b/bashrc.d/aws deleted file mode 100755 index 15e5166..0000000 --- a/bashrc.d/aws +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/env bash - -aws-switch() { - if [ -z "$1" ]; then - unset AWS_PROFILE - else - export AWS_PROFILE="$1" - fi -} diff --git a/bashrc.d/aws-vault b/bashrc.d/aws-vault deleted file mode 100755 index c1f1088..0000000 --- a/bashrc.d/aws-vault +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v aws-vault)" ]; then - if [ "$(command -v aws)" ]; then - aws() { aws-vault exec "${AWS_PROFILE:-default}" -- aws "$@"; } - fi -fi diff --git a/bashrc.d/bat b/bashrc.d/bat deleted file mode 100755 index 8ebb93a..0000000 --- a/bashrc.d/bat +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v bat)" ]; then - export BAT_THEME=zenburn - export HOMEBREW_BAT=1 - alias cat='bat' -fi diff --git a/bashrc.d/dircolors b/bashrc.d/dircolors deleted file mode 100755 index 55ac1d7..0000000 --- a/bashrc.d/dircolors +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v dircolors)" ]; then - eval "$(dircolors ~/.dircolors)" -elif [ "$(command -v gdircolors)" ]; then - eval "$(gdircolors ~/.dircolors)" -fi diff --git a/bashrc.d/direnv b/bashrc.d/direnv deleted file mode 100755 index 58212f0..0000000 --- a/bashrc.d/direnv +++ /dev/null @@ -1,5 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v direnv)" ]; then - eval "$(direnv hook bash)" -fi diff --git a/bashrc.d/dotnet b/bashrc.d/dotnet deleted file mode 100755 index b49675e..0000000 --- a/bashrc.d/dotnet +++ /dev/null @@ -1,5 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v dotnet)" ]; then - export DOTNET_CLI_TELEMETRY_OPTOUT=1 -fi diff --git a/bashrc.d/editor b/bashrc.d/editor deleted file mode 100755 index 6174246..0000000 --- a/bashrc.d/editor +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env bash - -# http://stuff-things.net/2014/12/16/working-with-emacsclient/ -# -if [ -z "$SSH_CONNECTION" ]; then - if [ "$(command -v code)" ]; then - export EDITOR='code --wait' - else - export EDITOR='emacsclient -c' - fi - export ALTERNATE_EDITOR='' -else - EDITOR=$(type -P emacs || type -P vim || type -P vi) - export EDITOR -fi -export VISUAL=$EDITOR diff --git a/bashrc.d/emacs b/bashrc.d/emacs deleted file mode 100755 index 439c984..0000000 --- a/bashrc.d/emacs +++ /dev/null @@ -1,5 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v emacsclient)" ]; then - alias ec="emacsclient -c -n" -fi diff --git a/bashrc.d/exa b/bashrc.d/exa deleted file mode 100755 index ec92c5d..0000000 --- a/bashrc.d/exa +++ /dev/null @@ -1,12 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v exa)" ]; then - export TIME_STYLE='long-iso' - alias ll='exa --all --long --header --git' - alias llx='exa --all --long --header --git --extended' - - if [ ! "$(command -v tree)" ]; then - alias tree='exa --tree --all --long --header --git' - alias treex='exa --tree --all --long --header --git --extended' - fi -fi diff --git a/bashrc.d/gh b/bashrc.d/gh deleted file mode 100755 index 1ae6b3d..0000000 --- a/bashrc.d/gh +++ /dev/null @@ -1,10 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v gh)" ]; then - eval "$(gh completion -s bash)" -fi - -if [ -z "${GH_USERNAME}" ]; then - GH_USERNAME="$(logname)" - export GH_USERNAME -fi diff --git a/bashrc.d/homebrew b/bashrc.d/homebrew deleted file mode 100755 index 79fa81c..0000000 --- a/bashrc.d/homebrew +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v brew)" ]; then - # If set, Homebrew will not send analytics. See: - export HOMEBREW_NO_ANALYTICS=1 - - # If set, Homebrew will not permit redirects from secure HTTPS - # to insecure HTTP. - # - # While ensuring your downloads are fully secure, this is likely - # to cause from-source SourceForge, some GNU & GNOME based - # formulae to fail to download. - export HOMEBREW_NO_INSECURE_REDIRECT=1 - - # abort installation of cask if no checksum is defined - export HOMEBREW_CASK_OPTS=--require-sha - - if [ -f "$(brew --prefix)/etc/bash_completion" ]; then - # shellcheck source=/dev/null - . "$(brew --prefix)/etc/bash_completion" - fi -fi diff --git a/bashrc.d/hub b/bashrc.d/hub deleted file mode 100755 index d05817c..0000000 --- a/bashrc.d/hub +++ /dev/null @@ -1,5 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v hub)" ]; then - eval "$(hub alias -s)" -fi diff --git a/bashrc.d/jenv b/bashrc.d/jenv deleted file mode 100644 index 5660b37..0000000 --- a/bashrc.d/jenv +++ /dev/null @@ -1,5 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v jenv)" ]; then - eval "$(jenv init -)" -fi diff --git a/bashrc.d/terraform b/bashrc.d/terraform deleted file mode 100755 index c4de46c..0000000 --- a/bashrc.d/terraform +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v terraform)" ]; then - complete -C "$(command -v terraform)" terraform - - if [ "$(command -v aws-vault)" ]; then - terraform() { aws-vault exec "${AWS_PROFILE:-default}" -- terraform "$@"; } - fi -fi diff --git a/config/1Password/ssh/agent.toml b/config/1Password/ssh/agent.toml new file mode 100644 index 0000000..0ee1411 --- /dev/null +++ b/config/1Password/ssh/agent.toml @@ -0,0 +1,8 @@ +# Auth key first: the agent offers keys in listed order. The signing key must be +# listed too — op-ssh-sign can only reach keys enabled here once a custom config +# exists (it does not fall back to the default Private/Personal vaults). +[[ssh-keys]] +item = "Personal SSH auth (ed25519)" + +[[ssh-keys]] +item = "Git SSH signing (ed25519)" diff --git a/config/bat/themes/zenburn.tmTheme b/config/bat/themes/zenburn.tmTheme new file mode 100644 index 0000000..ead5f60 --- /dev/null +++ b/config/bat/themes/zenburn.tmTheme @@ -0,0 +1,829 @@ + + + + + author + Jani Nurminen. Adapted and modified by Colin T.A. Gray and William D. Neumann + name + zenburn + settings + + + settings + + background + #393939 + caret + #D6D6D6 + foreground + #DEDEDE + gutter + #393939 + gutterForeground + #DEDEDE + invisibles + #A5A5A5 + lineHighlight + #202020 + selection + #838383AA + + + + name + Comment + scope + comment + settings + + foreground + #87AE86 + + + + name + preprocessor + scope + punctuation.definition.preprocessor + settings + + foreground + #E8BC92 + + + + name + phpdoc + scope + keyword.other.phpdoc + settings + + foreground + #568E4D + + + + name + comment punctuation (/*, #, //) + scope + punctuation.definition.comment, punctuation.whitespace.comment + settings + + foreground + #A0CFA1 + + + + name + embedded ruby in string delimiters + scope + punctuation.section.embedded, punctuation.section.interpolation + settings + + foreground + #898989 + + + + name + Line-number directives + scope + keyword.other.directive.line-number + settings + + fontStyle + underline + + + + name + Characters + scope + constant.character + settings + + foreground + #D58684 + + + + name + User-defined constant + scope + constant.other + settings + + foreground + #D58684 + + + + name + String + scope + string, string.unquoted + settings + + foreground + #D68686 + + + + name + Heredoc + scope + string.unquoted.heredoc + settings + + foreground + #D6D6D6 + + + + name + Number + scope + support.constant.numeric, constant.numeric + settings + + foreground + #87D6D5 + + + + name + Built-in constant + scope + constant, support.constant + settings + + fontStyle + bold + foreground + #D6D6AE + + + + name + Other constant + scope + variable.other.constant + settings + + foreground + #D6D6AE + + + + name + Language Keyword + scope + keyword, keyword.control, entity.other.attribute-name + settings + + foreground + #FED6AF + + + + name + Instance Variable + scope + variable.other.readwrite.instance + settings + + foreground + #FED6AF + + + + name + Module Keyword + scope + entity.name.module,support.other.module + settings + + fontStyle + bold + foreground + #FF8000 + + + + name + Operators + scope + keyword.operator + settings + + foreground + #ECECEC + + + + name + Floating-point infix operators + scope + source.ocaml keyword.operator.symbol.infix.floating-point + settings + + fontStyle + underline + + + + name + Floating-point prefix operators + scope + source.ocaml keyword.operator.symbol.prefix.floating-point + settings + + fontStyle + underline + + + + name + Storage Types + scope + storage.type , storage.modifier , support.type + settings + + foreground + #FFFB9D + + + + name + Variant Types + scope + entity.name.class.variant + settings + + foreground + #4080A0 + + + + name + Type name + scope + entity.name.type , entity.other + settings + + foreground + #D6D6D6 + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + foreground + #D78D1B + + + + name + Type name + scope + storage.type.user-defined + settings + + foreground + #FFE000 + + + + name + Class type name + scope + entity.name.type , entity.name.type.class , entity.other.attribute-name.class.css , entity.name.class + settings + + foreground + #F4A020 + + + + name + Invalid + scope + invalid + settings + + fontStyle + bold italic underline + foreground + #FFCCEE + + + + name + html attribute + scope + entity.other.attribute-name.html + settings + + fontStyle + bold + foreground + #D6D7AF + + + + name + html entity + scope + entity.name.tag + settings + + foreground + #D6D7AF + + + + name + <?php + scope + punctuation.section.embedded.begin.php,punctuation.section.embedded.end.php + settings + + foreground + #898989 + + + + name + function + scope + support.function.construct + settings + + foreground + #FED6AF + + + + name + $variable prefix + scope + punctuation.definition.variable + settings + + foreground + #FED6AF + + + + name + function/method + scope + support.function,entity.name.function + settings + + foreground + #FFFD87 + + + + name + built-in function + scope + support.function + settings + + foreground + #C7BA18 + + + + name + braces + scope + punctuation.brace + settings + + foreground + #78CECC80 + + + + name + string begin + scope + punctuation.definition.string.begin,punctuation.definition.string.end + settings + + foreground + #D6D6D680 + + + + name + html tag begin/end + scope + punctuation.definition.tag.begin.html,punctuation.definition.tag.end.html,meta.tag.structure.any.html + settings + + fontStyle + bold + foreground + #FED5AE94 + + + + name + yaml entity + scope + entity.name.tag.yaml + settings + + fontStyle + bold + foreground + #FED6AF + + + + name + unquoted yaml string + scope + punctuation.definition.entry + settings + + foreground + #D6D6D6 + + + + name + SQL + scope + keyword.other.DML.sql, keyword.other.data-integrity.sql + settings + + fontStyle + bold + foreground + #B7B7B7 + + + + name + other SQL + scope + source.sql, constant.other.database-name.sql, constant.other.table-name.sql, keyword.operator.star + settings + + fontStyle + bold + foreground + #95BFF3 + + + + name + diff + scope + source.diff + settings + + background + #393939 + foreground + #FFFFFF + + + + name + diff.toc + scope + source.diff meta.diff.comment, source.diff meta.toc-list.comment.diff + settings + + background + #9F9D15 + foreground + #FFFFFF + + + + name + diff from-file + scope + meta.diff.header.from-file + settings + + background + #393939 + fontStyle + bold + foreground + #CA7172 + + + + name + diff to-file + scope + meta.diff.header.to-file + settings + + background + #393939 + fontStyle + bold + foreground + #60B38A + + + + name + diff range + scope + meta.diff.range.unified + settings + + background + #393939 + foreground + #8CD0D3 + + + + name + diff inserted + scope + markup.inserted.diff + settings + + background + #393939 + foreground + #60B38A + + + + name + diff deleted + scope + markup.deleted.diff + settings + + background + #393939 + foreground + #CA7172 + + + + name + regex + scope + string.regexp + settings + + foreground + #C76F41 + + + + name + regex - repitition + scope + string.regexp.arbitrary-repitition + settings + + foreground + #9E6A5F + + + + name + regex - repitition {} + scope + punctuation.definition.arbitrary-repitition + settings + + foreground + #FFFFFF5E + + + + name + regex - character class + scope + string.regexp.character-class + settings + + foreground + #CB8E81 + + + + name + regex - character class [] + scope + punctuation.definition.character-class + settings + + foreground + #FFFFFF5E + + + + name + markdown inline code + scope + markup.raw.inline.markdown + settings + + foreground + #FED6AF + + + + name + links + scope + markup.heading + settings + + fontStyle + bold + + + + name + links + scope + markup.heading.1 + settings + + foreground + #E8DE9B + + + + name + links + scope + markup.heading.2 + settings + + foreground + #D7CD8F + + + + name + links + scope + markup.heading.3 + settings + + foreground + #C5BC83 + + + + name + links + scope + markup.heading.4 + settings + + foreground + #B3AB77 + + + + name + links + scope + markup.heading.5 + settings + + foreground + #A0996B + + + + name + links + scope + markup.heading.6 + settings + + foreground + #8F895F + + + + name + markup underline + scope + markup.underline + settings + + fontStyle + underline + + + + name + markup italic + scope + markup.italic + settings + + fontStyle + italic + + + + name + markdown links + scope + markup.underline.link + settings + + foreground + #4080A0 + + + + name + markup bold + scope + markup.bold + settings + + fontStyle + bold + + + + name + Markdown link names + scope + meta.link.reference, meta.link.inline + settings + + foreground + #D58684 + + + + name + SublimeLinter Warning + scope + sublimelinter.mark.warning + settings + + foreground + #DDB700 + + + + name + markdown list + scope + punctuation.definition.list_item.markdown + settings + + fontStyle + bold + + + + name + SublimeLinter Gutter Mark + scope + sublimelinter.gutter-mark + settings + + foreground + #FFFFFF + + + + name + SublimeLinter Error + scope + sublimelinter.mark.error + settings + + foreground + #D02000 + + + + uuid + A34A7407-68B9-48E5-883E-E551F7561026 + + diff --git a/config/gh/config.yml b/config/gh/config.yml index d320be3..9344f04 100644 --- a/config/gh/config.yml +++ b/config/gh/config.yml @@ -10,3 +10,4 @@ pager: aliases: co: pr checkout sync: '!gh repo sync "${GH_USERNAME}"/"$(basename $(pwd))" && gh repo sync' +version: "1" diff --git a/config/git/allowed_signers b/config/git/allowed_signers new file mode 100644 index 0000000..581c272 --- /dev/null +++ b/config/git/allowed_signers @@ -0,0 +1,4 @@ +# Public keys trusted for verifying git signatures (ssh signing has no keyring, +# so trust must be declared explicitly). The principal must match the committer +# email. namespaces="git" limits the key to git signatures only. +celkins@users.noreply.github.com namespaces="git" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFm/VtE4MLt8wvsjwFdfeSLTKLoGuh6rLQ6Ze4uLTbEh diff --git a/config/git/config b/config/git/config index 8304488..5424cff 100644 --- a/config/git/config +++ b/config/git/config @@ -25,12 +25,6 @@ [branch] autosetuprebase = always -[color "diff-highlight"] - oldNormal = "red bold" - oldHighlight = "red bold 52" - newNormal = "green bold" - newHighlight = "green bold 22" - [color "status"] added = green changed = yellow @@ -40,6 +34,7 @@ [diff] tool = vscode + colorMoved = default [difftool] prompt = false @@ -59,14 +54,11 @@ [merge] tool = vscode + conflictStyle = zdiff3 [mergetool "vscode"] cmd = code --wait $MERGED -[pager] - diff = diff-so-fancy | less --tabs=4 -RFX - show = diff-so-fancy | less --tabs=4 -RFX - [push] default = current @@ -79,3 +71,30 @@ [user] name = Christopher Elkins email = celkins@users.noreply.github.com + +[core] + pager = delta + +[interactive] + diffFilter = delta --color-only + +[delta] + navigate = true + line-numbers = true + syntax-theme = zenburn + +# Signature *verification* is global, unlike signing below: log.showSignature is +# on for every repo, so without this any ssh-signed commit (including a +# colleague's in a work repo) errors out instead of just showing as untrusted. +[gpg "ssh"] + allowedSignersFile = ~/.config/git/allowed_signers + +# Commit signing, scoped to the personal GitHub namespace by remote URL, so work +# repos stay unsigned even on a personal machine and these dotfiles stay inert on +# a work machine. Both URL forms are covered because `gh` clones over ssh while +# older remotes here are https. Includes go last so they win over anything above. +[includeIf "hasconfig:remote.*.url:https://github.com/celkins/**"] + path = ~/.config/git/signing-1password + +[includeIf "hasconfig:remote.*.url:git@github.com:celkins/**"] + path = ~/.config/git/signing-1password diff --git a/config/git/signing-1password b/config/git/signing-1password new file mode 100644 index 0000000..308ea2c --- /dev/null +++ b/config/git/signing-1password @@ -0,0 +1,20 @@ +# Included only for repos whose remote is the personal GitHub namespace. +# See the includeIf blocks at the end of config/git/config. +# Signing is delegated to 1Password's op-ssh-sign, so no key material lives here. +# The key must also be listed in config/1Password/ssh/agent.toml: once a custom +# agent config exists, op-ssh-sign is limited to the keys enabled there and will +# not fall back to the default vaults. +# This is the dedicated *signing* key, deliberately distinct from the auth key; +# it is public, published at api.github.com/users/celkins/ssh_signing_keys. + +[user] + signingkey = ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFm/VtE4MLt8wvsjwFdfeSLTKLoGuh6rLQ6Ze4uLTbEh + +[gpg] + format = ssh + +[gpg "ssh"] + program = /Applications/1Password.app/Contents/MacOS/op-ssh-sign + +[commit] + gpgsign = true diff --git a/config/starship.toml b/config/starship.toml new file mode 100644 index 0000000..b02aba9 --- /dev/null +++ b/config/starship.toml @@ -0,0 +1,31 @@ +"$schema" = 'https://starship.rs/config-schema.json' + +add_newline = true +palette = "zenburn" + +[palettes.zenburn] +red = "#dca3a3" +green = "#7f9f7f" +yellow = "#f0dfaf" +blue = "#8cd0d3" +purple = "#dc8cc3" +orange = "#dfaf8f" +gray = "#709080" + +[character] +success_symbol = "[❯](green)" +error_symbol = "[❯](red)" + +[directory] +style = "blue" + +[git_branch] +style = "purple" + +[git_status] +style = "red" + +[cmd_duration] +min_time = 500 +format = "[$duration]($style) " +style = "yellow" diff --git a/dircolors/zenburn b/dircolors/zenburn deleted file mode 100644 index de1bb8e..0000000 --- a/dircolors/zenburn +++ /dev/null @@ -1,268 +0,0 @@ -# Zenburn color theme for the color GNU ls utility. -# Ivaylo Kuzev , 2014 - 2015 - -# Term Section -TERM Eterm -TERM ansi -TERM color-xterm -TERM con132x25 -TERM con132x30 -TERM con132x43 -TERM con132x60 -TERM con80x25 -TERM con80x28 -TERM con80x30 -TERM con80x43 -TERM con80x50 -TERM con80x60 -TERM cons25 -TERM console -TERM cygwin -TERM dtterm -TERM eterm-color -TERM gnome -TERM gnome-256color -TERM jfbterm -TERM konsole -TERM kterm -TERM linux -TERM linux-c -TERM mach-color -TERM mlterm -TERM putty -TERM rxvt -TERM rxvt-256color -TERM rxvt-cygwin -TERM rxvt-cygwin-native -TERM rxvt-unicode -TERM rxvt-unicode256 -TERM rxvt-unicode-256color -TERM screen -TERM screen-256color -TERM screen-256color-bce -TERM screen-bce -TERM screen-w -TERM screen.linux -TERM st -TERM st-meta -TERM st-256color -TERM st-meta-256color -TERM vt100 -TERM xterm -TERM xterm-16color -TERM xterm-256color -TERM xterm-88color -TERM xterm-color -TERM xterm-debian -TERM xterm-termite - -## Documentation -# -# Attribute codes: -# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color codes: -# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color codes: -# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -# -# Text 256 color coding: -# 38;5;COLOR_NUMBER -# Background 256 color coding: -# 48;5;COLOR_NUMBER - -# block device driver: -BLK 48;5;108;38;5;223;01 -# file with capability: -CAPABILITY 01;38;5;95 -# character device driver: -CHR 48;5;108;38;5;223;01 -# directory: -DIR 01;38;5;223 -# door: -DOOR 48;5;234;38;5;180;01 -# This is for files with execute permission: -EXEC 01;38;5;108 -# pipe: -FIFO 48;5;234;38;5;180;01 -# regular file: -#FILE 00 -# symbolic link: -LINK 48;5;234;38;5;223 -# normal (nonfilename) text: -#NORMAL 00 -# orphaned symbolic link: -ORPHAN 48;5;234;38;5;187 -# directory that is other-writable (o+w) and not sticky: -OTHER_WRITABLE 48;5;234;38;5;180 -# file that is setuid (u+s): -SETUID 48;5;234;38;5;66 -# file that is setgid (g+s): -SETGID 48;5;234;38;5;66 -# socket: -SOCK 48;5;234;38;5;180;01 -# directory with the sticky bit set (+t) and not other-writable: -STICKY 48;5;180;38;5;234 -# dir that is sticky and other-writable (+t,o+w): -STICKY_OTHER_WRITABLE 48;5;180;38;5;234 - -# archives -.7z 01;38;5;174 -.arj 01;38;5;174 -.bz2 01;38;5;174 -.bz 01;38;5;174 -.gz 01;38;5;174 -.rar 01;38;5;174 -.tar 01;38;5;174 -.tgz 01;38;5;174 -.tbz 01;38;5;174 -.tbz2 01;38;5;174 -.xz 01;38;5;174 -.zip 01;38;5;174 - -# packaged apps -.apk 01;38;5;95 -.deb 01;38;5;174 -.jad 01;38;5;95 -.jar 01;38;5;95 -.rpm 01;38;5;174 - -# images|graphics -.bmp 00;38;5;109 -.gif 00;38;5;109 -.ico 00;38;5;109 -.jpg 00;38;5;109 -.JPG 00;38;5;109 -.jpeg 00;38;5;109 -.png 00;38;5;109 -.svg 00;38;5;109 -.xbm 00;38;5;109 -.xpm 00;38;5;109 - -# audio formats -.aac 00;38;5;116 -.au 00;38;5;116 -.flac 00;38;5;116 -.mid 00;38;5;116 -.midi 00;38;5;116 -.mka 00;38;5;116 -.mp3 00;38;5;116 -.mpc 00;38;5;116 -.ogg 00;38;5;116 -.ra 00;38;5;116 -.wav 00;38;5;116 - -# video formats -.mov 00;38;5;66 -.mpg 00;38;5;66 -.mpeg 00;38;5;66 -.m2v 00;38;5;66 -.mkv 00;38;5;66 -.ogm 00;38;5;66 -.mp4 00;38;5;66 -.m4v 00;38;5;66 -.mp4v 00;38;5;66 -.vob 00;38;5;66 -.qt 00;38;5;66 -.nuv 00;38;5;66 -.wmv 00;38;5;66 -.asf 00;38;5;66 -.rm 00;38;5;66 -.rmvb 01;38;5;66 -.flc 00;38;5;66 -.avi 00;38;5;66 -.fli 00;38;5;66 -.flv 00;38;5;66 -.gl 00;38;5;66 -.m2ts 00;38;5;66 -.divx 00;38;5;66 -.webm 00;38;5;66 - -# shell -.awk 00;38;5;151 -.bash 00;38;5;151 -.bat 00;38;5;151 -.BAT 00;38;5;151 -.sed 00;38;5;151 -.sh 00;38;5;151 -.zsh 00;38;5;151 - -# build -*CMakeLists.txt 00;38;5;187 -.cabal 00;38;5;187 -*Makefile 00;38;5;187 -.mk 00;38;5;187 -.make 00;38;5;187 - -# source files -.c 01;38;5;187 -.h 01;38;5;187 -.s 01;38;5;187 -.cs 01;38;5;187 -.java 01;38;5;187 -.scala 01;38;5;187 -.hs 01;38;5;187 -.py 01;38;5;187 -.rb 01;38;5;187 -.php 01;38;5;187 -.pl 01;38;5;187 -.vim 01;38;5;187 -.js 01;38;5;187 -.coffee 01;38;5;187 -.go 01;38;5;187 -.lisp 01;38;5;187 -.scm 01;38;5;187 - -# documents -.txt 04;38;5;188 -.tex 04;38;5;188 -.html 04;38;5;188 -.xhtml 04;38;5;188 -.xml 04;38;5;188 -.md 04;38;5;188 -.mkd 04;38;5;188 -.markdown 04;38;5;188 -.org 04;38;5;188 -.pandoc 04;38;5;188 -.pdc 04;38;5;188 -.pdf 04;38;5;188 - -# Files of special interest -*rc 04;38;5;180 -.conf 04;38;5;180 -*Dockerfile 04;38;5;180 - -# meta -*README 04;38;5;187 -*LICENSE 04;38;5;187 -*AUTHORS 04;38;5;187 - -# version control -.gitignore 00;38;5;248 -.gitmodules 00;38;5;248 - -# logs and backups -.log 00;38;5;234 -.bak 00;38;5;234 -.aux 00;38;5;234 -.toc 00;38;5;234 -*~ 00;38;5;234 -*# 00;38;5;234 -.swp 00;38;5;234 -.tmp 00;38;5;234 -.temp 00;38;5;234 -.o 00;38;5;234 -.pyc 00;38;5;234 -.class 00;38;5;234 -.cache 00;38;5;234 - -# pacman files -.pacnew 48;5;95;38;5;108 -.pacsave 48;5;95;38;5;108 -.pacorig 48;5;95;38;5;108 -*PKGBUILD 00;38;5;110 - -# rpm files -.rpmsave 48;5;95;38;5;108 -.rpmorig 48;5;95;38;5;108 -.rpmnew 48;5;95;38;5;108 -.spec 00;38;5;110 diff --git a/direnvrc b/direnvrc deleted file mode 100644 index 758142a..0000000 --- a/direnvrc +++ /dev/null @@ -1,14 +0,0 @@ -#! /usr/bin/env bash - -if [ "$(command -v nodenv)" ]; then - NODE_VERSIONS="$(nodenv root)/versions" - NODE_VERSION_PREFIX='' - export NODE_VERSIONS NODE_VERSION_PREFIX -fi - -use_ruby() { - if [ -n "$(command -v rbenv)" ]; then - load_prefix "$(rbenv root)/versions/${1}" - layout_ruby - fi -} diff --git a/install.conf.yaml b/install.conf.yaml index b2fad1a..4d7bda0 100644 --- a/install.conf.yaml +++ b/install.conf.yaml @@ -2,16 +2,25 @@ - shell: - [git submodule update --init --recursive, Installing submodules] - - mkdir -m 700 -p ~/{.ssh,bin,pkg,src} + - mkdir -m 700 -p ~/{.ssh,bin} - link: - ~/.bash_logout: - ~/.bash_profile: - ~/.bashrc: - ~/.bashrc.d: + ~/.zshenv: + ~/.zprofile: + ~/.zshrc: + ~/.zshrc.d: + ~/.config/1Password/ssh/agent.toml: + create: true + path: config/1Password/ssh/agent.toml + ~/.config/bat/themes/zenburn.tmTheme: + create: true + path: config/bat/themes/zenburn.tmTheme ~/.config/gh/config.yml: create: true path: config/gh/config.yml + ~/.config/git/allowed_signers: + create: true + path: config/git/allowed_signers ~/.config/git/config: create: true path: config/git/config @@ -19,13 +28,19 @@ create: true force: true path: config/git/ignore + ~/.config/git/signing-1password: + create: true + path: config/git/signing-1password + ~/.config/starship.toml: + create: true + path: config/starship.toml ~/.curlrc: - ~/.dircolors: - path: dircolors/zenburn - ~/.direnvrc: ~/.inputrc: - ~/.profile: ~/.ssh/config: create: true path: ssh/config ~/.vimrc: + +- shell: + - - command -v bat >/dev/null 2>&1 && bat cache --build || true + - Building bat theme cache diff --git a/macos.conf.yaml b/macos.conf.yaml index f338c24..123bd69 100644 --- a/macos.conf.yaml +++ b/macos.conf.yaml @@ -6,4 +6,3 @@ - mkdir -p ~/.m2 ~/Library/Caches/m2/{repository,wrapper} && ln -fhs ~/Library/Caches/m2/{repository,wrapper} ~/.m2/ - mkdir -p ~/Library/KeyBindings && cp Library/KeyBindings/DefaultKeyBinding.dict ~/Library/KeyBindings/ - mkdir -p ~/Library/Caches/sbt && ln -fhs ~/Library/Caches/sbt ~/.sbt - - mkdir -p ~/.terraform.d ~/Library/Caches/terraform/plugins && ln -fhs ~/Library/Caches/terraform/plugins ~/.terraform.d/plugin-cache diff --git a/profile b/profile deleted file mode 100644 index 9d579aa..0000000 --- a/profile +++ /dev/null @@ -1,16 +0,0 @@ -# -*- mode: sh -*- - -LC_CTYPE='en_US.UTF-8'; export LC_CTYPE - -[ -d "${HOME}/bin" ] && PATH=${HOME}/bin:${PATH}; export PATH - -if [ -f "${HOME}/.gpg-agent-info" ]; then - . "${HOME}/.gpg-agent-info" - export GPG_AGENT_INFO -fi - -if [ -z "$GOPATH" ]; then -GOPATH=$HOME; export GOPATH -fi - -CDPATH=.:$GOPATH/src:$GOPATH/src/github.com:$GOPATH/src/github.com/celkins:$GOPATH/src/bitbucket.org:$GOPATH/src/bitbucket.org/celkins:$GOPATH/src/celkins.visualstudio.com diff --git a/ssh/config b/ssh/config index 1421065..ea339c5 100644 --- a/ssh/config +++ b/ssh/config @@ -1,3 +1,9 @@ +# Order matters: ssh is first-match-wins, so these run most specific to most +# general. Colima's generated blocks are host-specific; config.local holds +# machine-wide overrides (e.g. work machines pointing Host * at a Secure Enclave +# agent instead of 1Password) and so must still precede the defaults below. +# Missing Include targets are silently ignored, so both are inert where absent. +Include ~/.colima/ssh_config Include config.local Host * diff --git a/zprofile b/zprofile new file mode 100644 index 0000000..aed95ce --- /dev/null +++ b/zprofile @@ -0,0 +1,17 @@ +# -*- mode: sh -*- +# Login shells, after macOS /etc/zprofile (which runs path_helper). + +# Homebrew: sets PATH, MANPATH, INFOPATH, FPATH (zsh completions), HOMEBREW_PREFIX. +if [ -x /opt/homebrew/bin/brew ]; then + eval "$(/opt/homebrew/bin/brew shellenv)" +elif [ -x /usr/local/bin/brew ]; then + eval "$(/usr/local/bin/brew shellenv)" +fi + +# Personal bin ahead of the rest. +[ -d "${HOME}/bin" ] && export PATH="${HOME}/bin:${PATH}" + +GPG_TTY=$(tty) +export GPG_TTY + +[ -r "${HOME}/.zprofile.local" ] && . "${HOME}/.zprofile.local" diff --git a/zshenv b/zshenv new file mode 100644 index 0000000..9ae648d --- /dev/null +++ b/zshenv @@ -0,0 +1,13 @@ +# -*- mode: sh -*- +# Sourced for every zsh (login, interactive, scripts). Keep minimal. + +# macOS-native cache dir: the OS purges it under disk pressure and Time Machine +# excludes it, so regenerable data stays out of backups. XDG_CONFIG_HOME and +# XDG_DATA_HOME are deliberately left unset — the spec defaults (~/.config, +# ~/.local/share) are already what we want, and overriding DATA_HOME to +# ~/Library scattered tool dirs among Apple's own. +export XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/Library/Caches} + +export LC_CTYPE=en_US.UTF-8 + +[ -r "${HOME}/.zshenv.local" ] && . "${HOME}/.zshenv.local" diff --git a/zshrc b/zshrc new file mode 100644 index 0000000..a459833 --- /dev/null +++ b/zshrc @@ -0,0 +1,73 @@ +# -*- mode: sh -*- + +run_scripts() { + for script in "$1"/*(N); do + [ -x "$script" ] || continue + . "$script" + done +} + +export CLICOLOR='1' + +export PAGER='less' +export LESS='eiMRsXx4' +export LESSHISTFILE=- + +if command -v lesspipe.sh >/dev/null 2>&1; then + export LESSOPEN="|lesspipe.sh %s" +fi + +alias cd..='cd ..' +alias cp='cp -i' +alias md='mkdir -p' +alias mv='mv -i' +alias pbclean='pbpaste | pbcopy' +alias po='popd' +alias pu='pushd' +alias grep='grep --color=auto ' +alias map='xargs -n1' + +# Shell options +setopt ignore_eof # Ctrl-D does not exit the shell +setopt no_clobber # > won't overwrite an existing file; use >| to force +setopt auto_cd # a bare directory path cd's into it (replaces the '..' alias) +setopt auto_pushd # every cd pushes onto the dir stack, so po/pu walk back +setopt pushd_ignore_dups # ...without stacking consecutive duplicates +setopt no_case_glob # *.TXT matches .txt, like the completion matcher +setopt interactive_comments # allow '# comment' on the interactive line + +# History +HISTFILE="${HOME}/.zsh_history" +HISTSIZE=10000 +SAVEHIST=10000 +setopt share_history hist_ignore_dups hist_ignore_space +setopt hist_verify # !! / !$ expand onto the line instead of running immediately + +# Completion (replaces bash-completion) +# -u: Homebrew's completion dirs (/opt/homebrew/share/zsh/...) are owned by the +# admin account and group-writable, which compinit rejects as insecure and then +# ABORTS on — which silently breaks completion, including the case-insensitive +# matcher below. -u trusts them (consistent with already trusting brew's +# binaries). We can't chmod them (admin owns them, and brew resets the perms). +# Stricter alt: -i skips them but loses brew's tool completions. +autoload -Uz compinit && compinit -u +zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' + +# Word boundaries for the word widgets (Option+Delete, Option+arrows). +# zsh's default WORDCHARS includes - _ . / = etc., so backward-kill-word eats a +# whole hyphenated name or path. Empty means alphanumerics only, matching +# readline/bash: delete one token at a time. +WORDCHARS='' + +# Prefix history search on Up/Down (zsh's default is a plain history walk). +# The old ~/.inputrc also bound Alt+Delete to "delete the preceding word" — +# dropped, because zsh already binds ^[^? (Option+Delete) to backward-kill-word. +autoload -Uz up-line-or-beginning-search down-line-or-beginning-search +zle -N up-line-or-beginning-search +zle -N down-line-or-beginning-search +bindkey '^[[A' up-line-or-beginning-search +bindkey '^[[B' down-line-or-beginning-search + +run_scripts "${HOME}/.zshrc.d" + +[ -r "${HOME}/.zshrc.local" ] && . "${HOME}/.zshrc.local" diff --git a/zshrc.d/bat b/zshrc.d/bat new file mode 100755 index 0000000..c69396d --- /dev/null +++ b/zshrc.d/bat @@ -0,0 +1,8 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v bat >/dev/null 2>&1; then + export BAT_THEME=zenburn + export HOMEBREW_BAT=1 + alias cat='bat' +fi diff --git a/zshrc.d/editor b/zshrc.d/editor new file mode 100755 index 0000000..3c56403 --- /dev/null +++ b/zshrc.d/editor @@ -0,0 +1,10 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if [ -z "$SSH_CONNECTION" ] && command -v code >/dev/null 2>&1; then + export EDITOR='code --wait' +else + EDITOR=$(command -v vim || command -v vi) + export EDITOR +fi +export VISUAL=$EDITOR diff --git a/zshrc.d/eza b/zshrc.d/eza new file mode 100755 index 0000000..1197704 --- /dev/null +++ b/zshrc.d/eza @@ -0,0 +1,13 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v eza >/dev/null 2>&1; then + export TIME_STYLE='long-iso' + alias ll='eza -al --header --git --icons=auto' + alias llx='eza -al --header --git --extended --icons=auto' + + if ! command -v tree >/dev/null 2>&1; then + alias tree='eza --tree --all --long --header --git --icons=auto' + alias treex='eza --tree --all --long --header --git --extended --icons=auto' + fi +fi diff --git a/zshrc.d/fzf b/zshrc.d/fzf new file mode 100755 index 0000000..227e062 --- /dev/null +++ b/zshrc.d/fzf @@ -0,0 +1,18 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v fzf >/dev/null 2>&1; then + if command -v fd >/dev/null 2>&1; then + export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git' + export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" + fi + + # Zenburn picker colors + export FZF_DEFAULT_OPTS="--color=bg+:#3f3f3f,bg:#1f1f1f,fg:#dcdccc,fg+:#ffffff,hl:#dfaf8f,hl+:#f0dfaf,info:#7f9f7f,prompt:#dca3a3,pointer:#dca3a3,marker:#8cd0d3,spinner:#7f9f7f,header:#7f9f7f" + + if command -v bat >/dev/null 2>&1; then + export FZF_CTRL_T_OPTS="--preview 'bat --color=always --style=numbers --line-range=:200 {}'" + fi + + eval "$(fzf --zsh)" +fi diff --git a/zshrc.d/gh b/zshrc.d/gh new file mode 100755 index 0000000..931d8a5 --- /dev/null +++ b/zshrc.d/gh @@ -0,0 +1,11 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v gh >/dev/null 2>&1; then + eval "$(gh completion -s zsh)" +fi + +if [ -z "${GH_USERNAME}" ]; then + GH_USERNAME="$(logname)" + export GH_USERNAME +fi diff --git a/zshrc.d/homebrew b/zshrc.d/homebrew new file mode 100755 index 0000000..d44d6f1 --- /dev/null +++ b/zshrc.d/homebrew @@ -0,0 +1,7 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v brew >/dev/null 2>&1; then + export HOMEBREW_NO_ANALYTICS=1 + export HOMEBREW_NO_INSECURE_REDIRECT=1 +fi diff --git a/zshrc.d/mise b/zshrc.d/mise new file mode 100755 index 0000000..a653bd0 --- /dev/null +++ b/zshrc.d/mise @@ -0,0 +1,6 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v mise >/dev/null 2>&1; then + eval "$(mise activate zsh)" +fi diff --git a/bashrc.d/npm b/zshrc.d/npm similarity index 50% rename from bashrc.d/npm rename to zshrc.d/npm index 1e43583..1fd5789 100755 --- a/bashrc.d/npm +++ b/zshrc.d/npm @@ -1,3 +1,4 @@ -#! /usr/bin/env bash +#! /usr/bin/env zsh +# shellcheck shell=bash export NPM_CONFIG_CACHE=$XDG_CACHE_HOME/npm diff --git a/zshrc.d/starship b/zshrc.d/starship new file mode 100755 index 0000000..cbcd7be --- /dev/null +++ b/zshrc.d/starship @@ -0,0 +1,6 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v starship >/dev/null 2>&1; then + eval "$(starship init zsh)" +fi diff --git a/zshrc.d/zoxide b/zshrc.d/zoxide new file mode 100755 index 0000000..6dd91a4 --- /dev/null +++ b/zshrc.d/zoxide @@ -0,0 +1,6 @@ +#! /usr/bin/env zsh +# shellcheck shell=bash + +if command -v zoxide >/dev/null 2>&1; then + eval "$(zoxide init zsh)" +fi