initial commit

This commit is contained in:
Tony Miller 2025-08-21 22:37:11 +10:00 committed by Tony Miller
commit 23870a12dc
38 changed files with 7413 additions and 0 deletions

46
.agignore Normal file
View File

@ -0,0 +1,46 @@
node_modules
.oh-my-zsh/plugins
.config/zsh/custom/plugins
.keep
.asdf
.git
.yarn
.gem
Library
Applications
Movies/TV
Music/Music
zsh/custom/plugins
.config/broot
.localized
.DS_Store
.docker
.vim
.local/state
.local/lib
.local/share
.cache
.vpn
.sdkman
.cisco
.atlas-packages-cli
.Trash
.cups
.npm
.node-gyp
.doppler
.jssc
.zplug
.virtualenvs
.m2
.mvn
.pyenv
.build
.vscode/extensions
dist
Pictures
Music
Memory Alpha
Documents/Memory Alpha
__pycache__

193
.bashrc Normal file
View File

@ -0,0 +1,193 @@
#!/usr/bin/env bash
### DEFAULTS
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
[ -f ~/.config/bash/git-prompt.sh ] && . ~/.config/bash/git-prompt.sh
[ -f ~/.config/bash/private.sh ] && . ~/.config/bash/private.sh
### NVM
[ -d "$HOME/.config/nvm" ] \
&& export NVM_DIR="$HOME/.config/nvm" \
|| export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
### FZF
export FZF_DEFAULT_COMMAND='ag --skip-vcs-ignores --ignore .git --ignore node_modules -g ""'
[ -f /usr/share/doc/fzf/examples/key-bindings.bash ] \
&& source /usr/share/doc/fzf/examples/key-bindings.bash
do_cd_fzf() {
local parent="$1"
cd "${parent}/$(find "${parent}" \
-maxdepth 1 \
-mindepth 1 \
-type d | \
xargs -I '{}' basename '{}' | \
fzf)"
}
do_edit_fzf() {
local dir="$1"
pushd "$dir" > /dev/null
local target="$(fzf)"
if [ "${target}" != "" ]; then
vim "${target}"
fi
popd > /dev/null
}
fcd() {
local file
local dir
file=$(fzf +m -q "$1") && dir=$(dirname "$file") && cd "$dir"
}
do_checkout() {
git for-each-ref --format='%(refname:short)' \
$([ "$1" == "--remote" ] \
&& printf '%s' 'refs/remotes' \
|| printf '%s' 'refs/heads' ) \
| fzf \
| xargs -r git $([ "$1" == "--remote" ] \
&& printf '%s' 'checkout --track' \
|| printf '%s' 'checkout')
}
### GO
export GOPATH=~/.local/go
export PATH="$GOPATH/bin:$PATH"
### Helpers
function uber_download {
lftp -e "pget -c -n128 \"$1\"; quit"
}
function do_sdcv {
sdcv -c -0 "$1" | less -r
}
function do_ppwd {
pwd | xclip -selection clipboard
}
### ALIASES
alias d=docker
alias open=xdg-open
alias vim=nvim
alias ggg=gitui
alias gst="git status"
alias gco="do_checkout"
alias gcm="do_checkout --remote"
alias src="do_cd_fzf ${HOME}/src"
### HISTORY
# Avoid duplicates
HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend
# After each command, append to the history file and reread it
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
# UNLIMITED ~~POWER~~ HISTORY
HISTSIZE=-1
HISTFILESIZE=-1
### Customizations
shopt -s checkwinsize
# Completions
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
function prompt_text {
if [ "$EUID" -eq 0 ]; then
printf '[***ROOT***] # '
else
printf '$ '
fi
}
function prompt_color {
if [ "$EUID" -eq 0 ]; then
printf '\e[31m'
else
printf '\e[38;5;24m'
fi
}
function shorten_path {
local current_path=`pwd`
local last=`echo $current_path | sed -e 's/[^\/]*\///g'`
local path=""
[[ $current_path == "$HOME"* ]] && read -ra path <<< "~"
current_path=${current_path/"$HOME"/''}
current_path=${current_path:1}
IFS="/" read -ra current_path <<< "$current_path"
for x in "${current_path[@]}"
do
if [ "$x" == "$last" ];
then
path="${path}/${x}"
else
path="${path}/${x:0:1}"
fi
done
echo $path
}
# terminal titles
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# some colors
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
export EDITOR=nvim
export PATH="~/.local/bin:$PATH"
export PS1='\[$(prompt_color)\][$(shorten_path)]\[\e[31m\]$(__git_ps1)\n\[$(prompt_color)\]$(prompt_text)\[\033[m\]'
export LS_COLORS='di=1;34:ln=1;31:so=37:pi=1;93:ex=35:bd=37:cd=37:su=37:sg=37:tw=32:ow=32'
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

47
.config/Brewfile Normal file
View File

@ -0,0 +1,47 @@
tap "homebrew/autoupdate"
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/cask-fonts"
tap "homebrew/core"
tap "homebrew/services"
tap "yt-dlp/taps"
brew "ansible"
brew "choose-gui"
brew "cocoapods"
brew "eza"
brew "ffmpeg"
brew "fzf"
brew "git"
brew "git-lfs"
brew "htop"
brew "jq"
brew "lf"
brew "lftp"
brew "tree-sitter"
brew "neovim"
brew "pget"
brew "pyenv"
brew "pyenv-virtualenv"
brew "rclone"
brew "rustup"
brew "swift-format"
brew "syncthing", restart_service: :changed
brew "telnet"
brew "thefuck"
brew "trash", link: true
brew "wget"
brew "yt-dlp"
cask "alfred"
cask "bbedit"
cask "contexts"
cask "gnucash"
cask "hammerspoon"
cask "iterm2"
cask "musicbrainz-picard"
cask "orbstack"
cask "rectangle"
cask "syntax-highlight"
cask "visual-studio-code"

View File

@ -0,0 +1,64 @@
# Example configuration file, it's safe to copy this as the default config file without any modification.
# You don't have to copy this file to your instance,
# just run `./act_runner generate-config > config.yaml` to generate a config file.
log:
# The level of logging, can be trace, debug, info, warn, error, fatal
level: info
runner:
# Where to store the registration result.
file: "/Users/tmlr/Library/Caches/act_runner/runner"
# Execute how many tasks concurrently at the same time.
capacity: 1
# Extra environment variables to run jobs.
envs:
A_TEST_ENV_NAME_1: a_test_env_value_1
A_TEST_ENV_NAME_2: a_test_env_value_2
# Extra environment variables to run jobs from a file.
# It will be ignored if it's empty or the file doesn't exist.
env_file: .env
# The timeout for a job to be finished.
# Please note that the Gitea instance also has a timeout (3h by default) for the job.
# So the job could be stopped by the Gitea instance if it's timeout is shorter than this.
timeout: 1h
# The timeout for the runner to wait for running jobs to finish when shutting down.
# Any running jobs that haven't finished after this timeout will be cancelled.
shutdown_timeout: 0s
# Whether skip verifying the TLS certificate of the Gitea instance.
insecure: false
# The timeout for fetching the job from the Gitea instance.
fetch_timeout: 5s
# The interval for fetching the job from the Gitea instance.
fetch_interval: 2s
# The labels of a runner are used to determine which jobs the runner can run, and how to run them.
# Like: "macos-arm64:host" or "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest"
# Find more images provided by Gitea at https://gitea.com/gitea/runner-images .
# If it's empty when registering, it will ask for inputting labels.
# If it's empty when execute `daemon`, will use labels in `.runner` file.
labels:
- "macos-arm64:host"
cache:
# Enable cache server to use actions/cache.
enabled: true
# The directory to store the cache data.
# If it's empty, the cache data will be stored in $HOME/.cache/actcache.
dir: "/Users/tmlr/Library/Caches/act_runner"
# The host of the cache server.
# It's not for the address to listen, but the address to connect from job containers.
# So 0.0.0.0 is a bad choice, leave it empty to detect automatically.
host: ""
# The port of the cache server.
# 0 means to use a random available port.
port: 0
# The external cache server URL. Valid only when enable is true.
# If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself.
# The URL should generally end with "/".
external_server: ""
host:
# The parent directory of a job's working directory.
# If it's empty, $HOME/.cache/act/ will be used.
workdir_parent: "/Users/tmlr/Library/Caches/act_runner/jobs"

View File

@ -0,0 +1,41 @@
live_config_reload = true
[scrolling]
history = 100000
[font]
normal = { family = "Monaco", style = "Regular"}
size = 13
[window]
option_as_alt = "Both"
padding = { x = 5, y = 2 }
decorations = "Full"
[colors.primary]
foreground = "#4D4D4C"
background = "#F2F2F2"
[colors.normal]
black = "#4D4D4C"
red = "#D7235F"
green = "#718C00"
yellow = "#D75E00"
blue = "#4271AD"
magenta = "#8959A8"
cyan = "#0A94A1"
white = "#EEEEED"
[colors.bright]
black = "#4D4D4C"
red = "#D7235F"
green = "#718C00"
yellow = "#D75E00"
blue = "#4271AD"
magenta = "#8959A8"
cyan = "#0A94A1"
white = "#EEEEED"
[keyboard]
bindings = [
{ key = "Backspace", mods = "Command", chars = "\u001bU" }, #delete backwards
{ key = "z", mods = "Command", chars = "\u001f" } #cmd+z
]

531
.config/bash/git-prompt.sh Normal file
View File

@ -0,0 +1,531 @@
# bash/zsh git prompt support
#
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
# Distributed under the GNU General Public License, version 2.0.
#
# This script allows you to see repository status in your prompt.
#
# To enable:
#
# 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
# 2) Add the following line to your .bashrc/.zshrc:
# source ~/.git-prompt.sh
# 3a) Change your PS1 to call __git_ps1 as
# command-substitution:
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
# ZSH: setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
# the optional argument will be used as format string.
# 3b) Alternatively, for a slightly faster prompt, __git_ps1 can
# be used for PROMPT_COMMAND in Bash or for precmd() in Zsh
# with two parameters, <pre> and <post>, which are strings
# you would put in $PS1 before and after the status string
# generated by the git-prompt machinery. e.g.
# Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
# will show username, at-sign, host, colon, cwd, then
# various status string, followed by dollar and SP, as
# your prompt.
# ZSH: precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
# will show username, pipe, then various status string,
# followed by colon, cwd, dollar and SP, as your prompt.
# Optionally, you can supply a third argument with a printf
# format string to finetune the output of the branch status
#
# The repository status will be displayed only if you are currently in a
# git repository. The %s token is the placeholder for the shown status.
#
# The prompt status always includes the current branch name.
#
# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
# unstaged (*) and staged (+) changes will be shown next to the branch
# name. You can configure this per-repository with the
# bash.showDirtyState variable, which defaults to true once
# GIT_PS1_SHOWDIRTYSTATE is enabled.
#
# You can also see if currently something is stashed, by setting
# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
# then a '$' will be shown next to the branch name.
#
# If you would like to see if there're untracked files, then you can set
# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
# files, then a '%' will be shown next to the branch name. You can
# configure this per-repository with the bash.showUntrackedFiles
# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
# enabled.
#
# If you would like to see the difference between HEAD and its upstream,
# set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates you are behind, ">"
# indicates you are ahead, "<>" indicates you have diverged and "="
# indicates that there is no difference. You can further control
# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated list
# of values:
#
# verbose show number of commits ahead/behind (+/-) upstream
# name if verbose, then also show the upstream abbrev name
# legacy don't use the '--count' option available in recent
# versions of git-rev-list
# git always compare HEAD to @{upstream}
# svn always compare HEAD to your SVN upstream
#
# You can change the separator between the branch name and the above
# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
# is SP.
#
# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
# find one, or @{upstream} otherwise. Once you have set
# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
# setting the bash.showUpstream config variable.
#
# If you would like to see more information about the identity of
# commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE
# to one of these values:
#
# contains relative to newer annotated tag (v1.6.3.2~35)
# branch relative to newer tag or branch (master~4)
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
# default exactly matching tag
#
# If you would like a colored hint about the current dirty state, set
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
# the colored output of "git status -sb" and are available only when
# using __git_ps1 for PROMPT_COMMAND or precmd.
#
# If you would like __git_ps1 to do nothing in the case when the current
# directory is set up to be ignored by git, then set
# GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the
# repository level by setting bash.hideIfPwdIgnored to "false".
# check whether printf supports -v
__git_printf_supports_v=
printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1
# stores the divergence from upstream in $p
# used by GIT_PS1_SHOWUPSTREAM
__git_ps1_show_upstream ()
{
local key value
local svn_remote svn_url_pattern count n
local upstream=git legacy="" verbose="" name=""
svn_remote=()
# get some config options from git-config
local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
while read -r key value; do
case "$key" in
bash.showupstream)
GIT_PS1_SHOWUPSTREAM="$value"
if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
p=""
return
fi
;;
svn-remote.*.url)
svn_remote[$((${#svn_remote[@]} + 1))]="$value"
svn_url_pattern="$svn_url_pattern\\|$value"
upstream=svn+git # default upstream is SVN if available, else git
;;
esac
done <<< "$output"
# parse configuration values
for option in ${GIT_PS1_SHOWUPSTREAM}; do
case "$option" in
git|svn) upstream="$option" ;;
verbose) verbose=1 ;;
legacy) legacy=1 ;;
name) name=1 ;;
esac
done
# Find our upstream
case "$upstream" in
git) upstream="@{upstream}" ;;
svn*)
# get the upstream from the "git-svn-id: ..." in a commit message
# (git-svn uses essentially the same procedure internally)
local -a svn_upstream
svn_upstream=($(git log --first-parent -1 \
--grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
if [[ 0 -ne ${#svn_upstream[@]} ]]; then
svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]}
svn_upstream=${svn_upstream%@*}
local n_stop="${#svn_remote[@]}"
for ((n=1; n <= n_stop; n++)); do
svn_upstream=${svn_upstream#${svn_remote[$n]}}
done
if [[ -z "$svn_upstream" ]]; then
# default branch name for checkouts with no layout:
upstream=${GIT_SVN_ID:-git-svn}
else
upstream=${svn_upstream#/}
fi
elif [[ "svn+git" = "$upstream" ]]; then
upstream="@{upstream}"
fi
;;
esac
# Find how many commits we are ahead/behind our upstream
if [[ -z "$legacy" ]]; then
count="$(git rev-list --count --left-right \
"$upstream"...HEAD 2>/dev/null)"
else
# produce equivalent output to --count for older versions of git
local commits
if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
then
local commit behind=0 ahead=0
for commit in $commits
do
case "$commit" in
"<"*) ((behind++)) ;;
*) ((ahead++)) ;;
esac
done
count="$behind $ahead"
else
count=""
fi
fi
# calculate the result
if [[ -z "$verbose" ]]; then
case "$count" in
"") # no upstream
p="" ;;
"0 0") # equal to upstream
p="=" ;;
"0 "*) # ahead of upstream
p=">" ;;
*" 0") # behind upstream
p="<" ;;
*) # diverged from upstream
p="<>" ;;
esac
else
case "$count" in
"") # no upstream
p="" ;;
"0 0") # equal to upstream
p=" u=" ;;
"0 "*) # ahead of upstream
p=" u+${count#0 }" ;;
*" 0") # behind upstream
p=" u-${count% 0}" ;;
*) # diverged from upstream
p=" u+${count#* }-${count% *}" ;;
esac
if [[ -n "$count" && -n "$name" ]]; then
__git_ps1_upstream_name=$(git rev-parse \
--abbrev-ref "$upstream" 2>/dev/null)
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
p="$p \${__git_ps1_upstream_name}"
else
p="$p ${__git_ps1_upstream_name}"
# not needed anymore; keep user's
# environment clean
unset __git_ps1_upstream_name
fi
fi
fi
}
# Helper function that is meant to be called from __git_ps1. It
# injects color codes into the appropriate gitstring variables used
# to build a gitstring.
__git_ps1_colorize_gitstring ()
{
if [[ -n ${ZSH_VERSION-} ]]; then
local c_red='%F{red}'
local c_green='%F{green}'
local c_lblue='%F{blue}'
local c_clear='%f'
else
# Using \[ and \] around colors is necessary to prevent
# issues with command line editing/browsing/completion!
local c_red='\[\e[31m\]'
local c_green='\[\e[32m\]'
local c_lblue='\[\e[1;34m\]'
local c_clear='\[\e[0m\]'
fi
local bad_color=$c_red
local ok_color=$c_green
local flags_color="$c_lblue"
local branch_color=""
if [ $detached = no ]; then
branch_color="$ok_color"
else
branch_color="$bad_color"
fi
c="$branch_color$c"
z="$c_clear$z"
if [ "$w" = "*" ]; then
w="$bad_color$w"
fi
if [ -n "$i" ]; then
i="$ok_color$i"
fi
if [ -n "$s" ]; then
s="$flags_color$s"
fi
if [ -n "$u" ]; then
u="$bad_color$u"
fi
r="$c_clear$r"
}
__git_eread ()
{
local f="$1"
shift
test -r "$f" && read "$@" <"$f"
}
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
# when called from PS1 using command substitution
# in this mode it prints text to add to bash PS1 prompt (includes branch name)
#
# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
# when two arguments are given, the first is prepended and the second appended
# to the state string when assigned to PS1.
# The optional third parameter will be used as printf format string to further
# customize the output of the git-status string.
# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
__git_ps1 ()
{
# preserve exit status
local exit=$?
local pcmode=no
local detached=no
local ps1pc_start='\u@\h:\w '
local ps1pc_end='\$ '
local printf_format='[%s]'
case "$#" in
2|3) pcmode=yes
ps1pc_start="$1"
ps1pc_end="$2"
printf_format="${3:-$printf_format}"
# set PS1 to a plain prompt so that we can
# simply return early if the prompt should not
# be decorated
PS1="$ps1pc_start$ps1pc_end"
;;
0|1) printf_format="${1:-$printf_format}"
;;
*) return $exit
;;
esac
# ps1_expanded: This variable is set to 'yes' if the shell
# subjects the value of PS1 to parameter expansion:
#
# * bash does unless the promptvars option is disabled
# * zsh does not unless the PROMPT_SUBST option is set
# * POSIX shells always do
#
# If the shell would expand the contents of PS1 when drawing
# the prompt, a raw ref name must not be included in PS1.
# This protects the user from arbitrary code execution via
# specially crafted ref names. For example, a ref named
# 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
# shell to execute 'sudo rm -rf /' when the prompt is drawn.
#
# Instead, the ref name should be placed in a separate global
# variable (in the __git_ps1_* namespace to avoid colliding
# with the user's environment) and that variable should be
# referenced from PS1. For example:
#
# __git_ps1_foo=$(do_something_to_get_ref_name)
# PS1="...stuff...\${__git_ps1_foo}...stuff..."
#
# If the shell does not expand the contents of PS1, the raw
# ref name must be included in PS1.
#
# The value of this variable is only relevant when in pcmode.
#
# Assume that the shell follows the POSIX specification and
# expands PS1 unless determined otherwise. (This is more
# likely to be correct if the user has a non-bash, non-zsh
# shell and safer than the alternative if the assumption is
# incorrect.)
#
local ps1_expanded=yes
[ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
[ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
local repo_info rev_parse_exit_code
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
--is-bare-repository --is-inside-work-tree \
--short HEAD 2>/dev/null)"
rev_parse_exit_code="$?"
if [ -z "$repo_info" ]; then
return $exit
fi
local short_sha
if [ "$rev_parse_exit_code" = "0" ]; then
short_sha="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
fi
local inside_worktree="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
local bare_repo="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
local inside_gitdir="${repo_info##*$'\n'}"
local g="${repo_info%$'\n'*}"
if [ "true" = "$inside_worktree" ] &&
[ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&
[ "$(git config --bool bash.hideIfPwdIgnored)" != "false" ] &&
git check-ignore -q .
then
return $exit
fi
local r=""
local b=""
local step=""
local total=""
if [ -d "$g/rebase-merge" ]; then
__git_eread "$g/rebase-merge/head-name" b
__git_eread "$g/rebase-merge/msgnum" step
__git_eread "$g/rebase-merge/end" total
if [ -f "$g/rebase-merge/interactive" ]; then
r="|REBASE-i"
else
r="|REBASE-m"
fi
else
if [ -d "$g/rebase-apply" ]; then
__git_eread "$g/rebase-apply/next" step
__git_eread "$g/rebase-apply/last" total
if [ -f "$g/rebase-apply/rebasing" ]; then
__git_eread "$g/rebase-apply/head-name" b
r="|REBASE"
elif [ -f "$g/rebase-apply/applying" ]; then
r="|AM"
else
r="|AM/REBASE"
fi
elif [ -f "$g/MERGE_HEAD" ]; then
r="|MERGING"
elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
r="|CHERRY-PICKING"
elif [ -f "$g/REVERT_HEAD" ]; then
r="|REVERTING"
elif [ -f "$g/BISECT_LOG" ]; then
r="|BISECTING"
fi
if [ -n "$b" ]; then
:
elif [ -h "$g/HEAD" ]; then
# symlink symbolic ref
b="$(git symbolic-ref HEAD 2>/dev/null)"
else
local head=""
if ! __git_eread "$g/HEAD" head; then
return $exit
fi
# is it a symbolic ref?
b="${head#ref: }"
if [ "$head" = "$b" ]; then
detached=yes
b="$(
case "${GIT_PS1_DESCRIBE_STYLE-}" in
(contains)
git describe --contains HEAD ;;
(branch)
git describe --contains --all HEAD ;;
(describe)
git describe HEAD ;;
(* | default)
git describe --tags --exact-match HEAD ;;
esac 2>/dev/null)" ||
b="$short_sha..."
b="($b)"
fi
fi
fi
if [ -n "$step" ] && [ -n "$total" ]; then
r="$r $step/$total"
fi
local w=""
local i=""
local s=""
local u=""
local c=""
local p=""
if [ "true" = "$inside_gitdir" ]; then
if [ "true" = "$bare_repo" ]; then
c="BARE:"
else
b="GIT_DIR!"
fi
elif [ "true" = "$inside_worktree" ]; then
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
[ "$(git config --bool bash.showDirtyState)" != "false" ]
then
git diff --no-ext-diff --quiet || w="*"
git diff --no-ext-diff --cached --quiet || i="+"
if [ -z "$short_sha" ] && [ -z "$i" ]; then
i="#"
fi
fi
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
git rev-parse --verify --quiet refs/stash >/dev/null
then
s="$"
fi
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
[ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null
then
u="%${ZSH_VERSION+%}"
fi
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
__git_ps1_show_upstream
fi
fi
local z="${GIT_PS1_STATESEPARATOR-" "}"
# NO color option unless in PROMPT_COMMAND mode
if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
__git_ps1_colorize_gitstring
fi
b=${b##refs/heads/}
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
__git_ps1_branch_name=$b
b="\${__git_ps1_branch_name}"
fi
local f="$w$i$s$u"
local gitstring="$c$b${f:+$z$f}$r$p"
if [ $pcmode = yes ]; then
if [ "${__git_printf_supports_v-}" != yes ]; then
gitstring=$(printf -- "$printf_format" "$gitstring")
else
printf -v gitstring -- "$printf_format" "$gitstring"
fi
PS1="$ps1pc_start$gitstring$ps1pc_end"
else
printf -- "$printf_format" "$gitstring"
fi
return $exit
}

View File

@ -0,0 +1 @@
EDITOR=nvim

View File

@ -0,0 +1,2 @@
GOPATH=$HOME/.local/go
PATH=${GOPATH}/bin:$PATH

78
.config/git/config Normal file
View File

@ -0,0 +1,78 @@
# vim: :foldmethod=marker
[include]
path = ~/.config/git/local
[init]
defaultBranch = main
[core]
excludesFile = ~/.config/git/ignore
quotepath = false
[pull]
rebase = true
[alias]
df = difftool
[filter "lfs"]
required = true
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
[push]
autoSetupRemote = true
# Diffs and Merges {{{
[diff]
tool = Kaleidoscope
[difftool]
prompt = false
trustExitCode = true
[merge]
tool = Kaleidoscope
[mergetool]
prompt = false
conflictstyle = diff3
# }}}
# {{{ Neovim
[difftool "nvim"]
cmd = nvim -d \"$LOCAL\" \"$REMOTE\"
[mergetool "nvim"]
cmd = "nvim -d -c \"wincmd l\" -c \"norm ]c\" \"$LOCAL\" \"$MERGED\" \"$REMOTE\""
# }}}
# {{{ VSCode
[mergetool "vscode"]
cmd = code --wait --merge $REMOTE $LOCAL $BASE $MERGED
[difftool "vscode"]
cmd = code --wait --diff $REMOTE $LOCAL $BASE $MERGED
# }}}
# {{{ BBEdit
[difftool "bbdiff"]
cmd = bbdiff --resume \"$LOCAL\" \"$REMOTE\"
[mergetool "bbdiff"]
cmd = bbdiff --wait --resume \"$LOCAL\" \"$REMOTE\"
# }}}
# {{{ Kaleidoscope
[difftool "Kaleidoscope"]
cmd = ksdiff --partial-changeset --relative-path \"$MERGED\" -- \"$LOCAL\" \"$REMOTE\"
[mergetool "Kaleidoscope"]
cmd = ksdiff --merge --output \"$MERGED\" --base \"$BASE\" -- \"$LOCAL\" --snapshot \"$REMOTE\" --snapshot
trustExitCode = true
# }}}
[difftool "sourcetree"]
cmd = opendiff \"$LOCAL\" \"$REMOTE\"
path =
[mergetool "sourcetree"]
cmd = /Applications/Sourcetree.app/Contents/Resources/opendiff-w.sh \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\"
trustExitCode = true
[user]
name = Tony Miller
email = aermolenko@atlassian.com
[trace2]
eventTarget = af_unix:/Users/aermolenko/.gittrace/trace.sock
eventBrief = true
eventNesting = 1
configparams = custom.metacommands

4
.config/git/ignore Normal file
View File

@ -0,0 +1,4 @@
*.swp
**/.claude/settings.local.json

View File

@ -0,0 +1,40 @@
// Note:
// If the default key layout is lower case,
// and you want to use `Shift + q` to trigger the exit event,
// the setting should like this `exit: Some(( code: Char('Q'), modifiers: "SHIFT")),`
// The Char should be upper case, and the modifier should be set to "SHIFT".
//
// Note:
// find `KeysList` type in src/keys/key_list.rs for all possible keys.
// every key not overwritten via the config file will use the default specified there
(
open_help: Some(( code: F(1), modifiers: "")),
move_left: Some(( code: Char('h'), modifiers: "")),
move_right: Some(( code: Char('l'), modifiers: "")),
move_up: Some(( code: Char('k'), modifiers: "")),
move_down: Some(( code: Char('j'), modifiers: "")),
popup_up: Some(( code: Char('p'), modifiers: "CONTROL")),
popup_down: Some(( code: Char('n'), modifiers: "CONTROL")),
page_up: Some(( code: Char('b'), modifiers: "CONTROL")),
page_down: Some(( code: Char('f'), modifiers: "CONTROL")),
home: Some(( code: Char('g'), modifiers: "")),
end: Some(( code: Char('G'), modifiers: "SHIFT")),
shift_up: Some(( code: Char('K'), modifiers: "SHIFT")),
shift_down: Some(( code: Char('J'), modifiers: "SHIFT")),
edit_file: Some(( code: Char('I'), modifiers: "SHIFT")),
status_reset_item: Some(( code: Char('U'), modifiers: "SHIFT")),
diff_reset_lines: Some(( code: Char('u'), modifiers: "")),
diff_stage_lines: Some(( code: Char('s'), modifiers: "")),
stashing_save: Some(( code: Char('w'), modifiers: "")),
stashing_toggle_index: Some(( code: Char('m'), modifiers: "")),
stash_open: Some(( code: Char('l'), modifiers: "")),
abort_merge: Some(( code: Char('M'), modifiers: "SHIFT")),
)

File diff suppressed because it is too large Load Diff

292
.config/nvim/init.lua Normal file
View File

@ -0,0 +1,292 @@
-- vim: :foldmethod=marker
-- === PACKAGE MANAGEMENT === {{{1
local function ensure_plugin(category, name, git_url, opts)
opts = opts or {}
local pack_path = os.getenv("HOME") .. "/.config/nvim/pack/" .. category .. "/" .. (opts.opt and "opt" or "start")
local plugin_path = pack_path .. "/" .. name
-- Create pack directory if it doesn't exist
vim.fn.system("mkdir -p " .. pack_path)
-- Check if plugin exists
if vim.fn.isdirectory(plugin_path) == 0 then
print("Installing " .. name .. "...")
local result = vim.fn.system("git clone --depth=1 " .. git_url .. " " .. plugin_path)
if vim.v.shell_error == 0 then
print("" .. name .. " installed successfully")
else
print("✗ Failed to install " .. name .. ": " .. result)
return false
end
end
-- Load optional plugin if requested
if opts.opt and opts.load then
vim.cmd("packadd " .. name)
end
return true
end
-- Plugin definitions - add more as needed
local plugins = {
-- Colorschemes
{"colors", "papercolor-theme", "https://github.com/NLKNguyen/papercolor-theme.git"},
{"colors", "tokyonight.nvim", "https://github.com/folke/tokyonight.nvim.git"},
-- Essential plugins
{"editor", "telescope.nvim", "https://github.com/nvim-telescope/telescope.nvim.git"},
{"editor", "plenary.nvim", "https://github.com/nvim-lua/plenary.nvim.git"}, -- telescope dependency
{"editor", "nvim-web-devicons", "https://github.com/nvim-tree/nvim-web-devicons.git"}, -- telescope dependency
-- LSP and completion
{"lsp", "nvim-lspconfig", "https://github.com/neovim/nvim-lspconfig.git"},
{"lsp", "mason.nvim", "https://github.com/williamboman/mason.nvim.git"},
{"lsp", "mason-lspconfig.nvim", "https://github.com/williamboman/mason-lspconfig.nvim.git"},
{"lsp", "nvim-cmp", "https://github.com/hrsh7th/nvim-cmp.git"},
{"lsp", "cmp-nvim-lsp", "https://github.com/hrsh7th/cmp-nvim-lsp.git"},
{"lsp", "cmp-buffer", "https://github.com/hrsh7th/cmp-buffer.git"},
{"lsp", "cmp-path", "https://github.com/hrsh7th/cmp-path.git"},
{"lsp", "LuaSnip", "https://github.com/L3MON4D3/LuaSnip.git"},
{"lsp", "cmp_luasnip", "https://github.com/saadparwaiz1/cmp_luasnip.git"},
-- Treesitter
{"syntax", "nvim-treesitter", "https://github.com/nvim-treesitter/nvim-treesitter.git"},
-- Git integration
{"git", "gitsigns.nvim", "https://github.com/lewis6991/gitsigns.nvim.git"},
-- Quality of life
{"editor", "which-key.nvim", "https://github.com/folke/which-key.nvim.git"},
{"editor", "Comment.nvim", "https://github.com/numToStr/Comment.nvim.git"},
{"editor", "nvim-surround", "https://github.com/kylechui/nvim-surround.git"},
}
-- Install all plugins
for _, plugin in ipairs(plugins) do
ensure_plugin(plugin[1], plugin[2], plugin[3], plugin[4])
end
-- === CORE SETTINGS === {{{1
local o = vim.o
local t = vim.t
local v = vim.v
local g = vim.g
local fn = vim.fn
local opt = vim.opt
local cmd = vim.cmd
local api = vim.api
local loop = vim.loop
local keys = vim.keymap
-- Globals
g.mapleader = "\\"
-- Helper function
local function has(val)
return fn.has(val) == 1
end
-- === APPEARANCE === {{{1
-- Basic UI
o.guifont = "Monaco:h13"
o.relativenumber = true
o.number = true
o.signcolumn = "yes"
o.termguicolors = true
o.laststatus = 2
o.statusline = "%f %h%w%m%y%r%=%(%l,%c%V %= %PT%)"
-- Colorscheme and dark mode integration
local function change_background()
o.background = "light"
cmd("colorscheme PaperColor")
cmd("redraw!")
end
if has("gui_macvim") then
local AutoDark = api.nvim_create_augroup("AutoDark", {clear = true})
api.nvim_create_autocmd({"OSAppearanceChanged"}, {
pattern = "*",
group = AutoDark,
callback = change_background
})
else
change_background()
end
-- === EDITOR BEHAVIOR === {{{1
-- Reading and saving
o.autoread = true
opt.clipboard:append("unnamedplus")
-- Indentation
o.autoindent = true
o.expandtab = true
o.tabstop = 2
o.shiftwidth = 2
-- Folding
o.foldmethod = "syntax"
-- Splits
opt.splitright = true
opt.splitbelow = true
-- Editing
opt.iskeyword:append("-")
-- Search
o.ignorecase = true
o.smartcase = true
o.hlsearch = true
o.incsearch = true
-- === PLUGIN CONFIGURATION === {{{1
-- Telescope
pcall(function()
require('telescope').setup({
defaults = {
file_ignore_patterns = {"node_modules", ".git/"}
}
})
end)
-- Which-key
pcall(function()
require('which-key').setup({})
end)
-- Comment.nvim
pcall(function()
require('Comment').setup()
end)
-- nvim-surround
pcall(function()
require('nvim-surround').setup()
end)
-- Gitsigns
pcall(function()
require('gitsigns').setup()
end)
-- Mason (LSP installer)
pcall(function()
require('mason').setup()
require('mason-lspconfig').setup({
ensure_installed = {"lua_ls", "ts_ls", "pyright", "rust_analyzer"}
})
end)
-- LSP Configuration
pcall(function()
local lspconfig = require('lspconfig')
local capabilities = require('cmp_nvim_lsp').default_capabilities()
-- Common LSP setup
local servers = {"lua_ls", "ts_ls", "pyright", "rust_analyzer"}
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup({
capabilities = capabilities
})
end
end)
-- Completion setup
pcall(function()
local cmp = require('cmp')
local luasnip = require('luasnip')
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
['<C-d>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<CR>'] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'luasnip' },
}, {
{ name = 'buffer' },
{ name = 'path' },
})
})
end)
-- Treesitter
pcall(function()
require('nvim-treesitter.configs').setup({
ensure_installed = {"lua", "typescript", "javascript", "python", "rust", "html", "css"},
highlight = { enable = true },
indent = { enable = true }
})
end)
-- === AUTOCMDS === {{{1
cmd("filetype plugin on")
-- TypeScript formatting on save
local TypescriptSave = api.nvim_create_augroup("TypescriptSave", {clear = true})
api.nvim_create_autocmd({"BufWritePost"}, {
pattern = "*.ts",
group = TypescriptSave,
command = "silent! !yarn prettier -w <afile>:p:S"
})
-- Diff mode settings
api.nvim_create_autocmd({"VimEnter"}, {
pattern = {"*"},
callback = function()
if o.diff then
o.wrap = true
keys.set("n", "ZZ", ":qa<Enter>")
cmd("cnoremap <expr> q<CR> 'qa<CR>'")
end
end
})
-- === KEYMAPS === {{{1
-- Leader key mappings
keys.set("n", "<Leader>rr", ":source $MYVIMRC<CR>", {desc = "Reload config"})
-- Basic editing
keys.set("i", "jk", "<Esc>", {desc = "Exit insert mode"})
keys.set("n", "x", '"_x', {desc = "Delete without copying"})
-- Telescope mappings
keys.set("n", "<Leader>ff", ":Telescope find_files<CR>", {desc = "Find files"})
keys.set("n", "<Leader>fg", ":Telescope live_grep<CR>", {desc = "Live grep"})
keys.set("n", "<Leader>fb", ":Telescope buffers<CR>", {desc = "Find buffers"})
keys.set("n", "<Leader>fh", ":Telescope help_tags<CR>", {desc = "Help tags"})
-- LSP mappings
keys.set("n", "gd", vim.lsp.buf.definition, {desc = "Go to definition"})
keys.set("n", "gD", vim.lsp.buf.declaration, {desc = "Go to declaration"})
keys.set("n", "gr", vim.lsp.buf.references, {desc = "References"})
keys.set("n", "gi", vim.lsp.buf.implementation, {desc = "Implementation"})
keys.set("n", "K", vim.lsp.buf.hover, {desc = "Hover documentation"})
keys.set("n", "<Leader>ca", vim.lsp.buf.code_action, {desc = "Code actions"})
keys.set("n", "<Leader>rn", vim.lsp.buf.rename, {desc = "Rename"})
keys.set("n", "<Leader>d", vim.diagnostic.open_float, {desc = "Show diagnostics"})
keys.set("n", "[d", vim.diagnostic.goto_prev, {desc = "Previous diagnostic"})
keys.set("n", "]d", vim.diagnostic.goto_next, {desc = "Next diagnostic"})
-- Window navigation
keys.set("n", "<C-h>", "<C-w>h", {desc = "Window left"})
keys.set("n", "<C-j>", "<C-w>j", {desc = "Window down"})
keys.set("n", "<C-k>", "<C-w>k", {desc = "Window up"})
keys.set("n", "<C-l>", "<C-w>l", {desc = "Window right"})
-- Clear search highlighting
keys.set("n", "<Leader>nh", ":nohl<CR>", {desc = "Clear highlights"})

10
.config/rectangle Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
defaults write com.knollsoft.Rectangle maximize -dict-add keyCode -float 3 modifierFlags -float 1835008
defaults write com.knollsoft.Rectangle maximizeHeight -dict-add keyCode -float 40 modifierFlags -float 1835008
defaults write com.knollsoft.Rectangle larger -dict-add keyCode -float 37 modifierFlags -float 1835008
defaults write com.knollsoft.Rectangle smaller -dict-add keyCode -float 4 modifierFlags -float 1835008
defaults write com.knollsoft.Rectangle specified -dict-add keyCode -float 38 modifierFlags -float 1835008
defaults write com.knollsoft.Rectangle specifiedHeight -float 818
defaults write com.knollsoft.Rectangle specifiedWidth -float 1152
defaults write com.knollsoft.Rectangle sizeOffset -float 280

4
.config/scroll-reverser Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
defaults write com.pilotmoon.scroll-reverser ReverseTrackpad -float 0
defaults write com.pilotmoon.scroll-reverser InvertScrollingOn -float 1

File diff suppressed because it is too large Load Diff

View File

View File

@ -0,0 +1,26 @@
# The Fuck settings file
#
# The rules are defined as in the example bellow:
#
# rules = ['cd_parent', 'git_push', 'python_command', 'sudo']
#
# The default values are as follows. Uncomment and change to fit your needs.
# See https://github.com/nvbn/thefuck#settings for more information.
#
# rules = [<const: All rules enabled>]
# exclude_rules = []
# wait_command = 3
# require_confirmation = True
# no_colors = False
# debug = False
# priority = {}
# history_limit = None
# alter_history = True
# wait_slow_command = 15
# slow_commands = ['lein', 'react-native', 'gradle', './gradlew', 'vagrant']
# repeat = False
# instant_mode = False
# num_close_matches = 3
# env = {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'}
# excluded_search_path_prefixes = []

3
.gitconfig Normal file
View File

@ -0,0 +1,3 @@
[include]
path = ~/.config/git/config

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*

342
.hammerspoon/init.lua Normal file
View File

@ -0,0 +1,342 @@
-- vim: :foldmethod=marker
hs.application.enableSpotlightForNameSearches(true)
local utils = hs.fnutils
local DEFAULTS = {
["EDITOR"] = {"BBEdit"},
["CHAT"] = {"Telegram"},
["MESSENGER"] = {"Messages"},
["MUSIC"] = {"Doppler"},
}
local APPS = {
browser = {"Safari"},
editors = {DEFAULTS["EDITOR"], {"Xcode"}, {"Code", "Visual Studio Code"}, {"IntelliJ IDEA"}},
chats = {{"Telegram"}},
messengers = {{"Telegram"}},
music = {DEFAULTS["MUSIC"], {"Music"}},
calendar = {"Calendar"},
terminal = {"iTerm", "iTerm2"},
videocalls = {}
}
-- Watchers {{{1
-- Cfg Watcher {{{2
function reload(files)
doReload = false
for _,file in pairs(files) do
if file:sub(-4) == ".lua" then
doReload = true
end
end
if doReload then
hs.reload()
end
end
cfgWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reload):start()
hs.alert.show("Config loaded")
-- Apps {{{1
-- Listeners {{{2
local listeners = {}
appWatcher = hs.application.watcher.new(function(name, event, app)
for i, v in ipairs(listeners) do
v(name, event, app)
end
end):start()
function app_listen(func)
listeners[#listeners+1] = func
end
-- {{{3 Terminal(s)
app_listen(function(name, event, app)
if app_matches(app, APPS["terminal"]) and event == hs.application.watcher.deactivated then
-- Don't hide terminal windows that have "claude" in the title
local shouldHide = true
for _, window in ipairs(app:allWindows()) do
if window:title() and string.find(string.lower(window:title()), "claude") then
shouldHide = false
break
end
end
if shouldHide then
app:hide()
end
elseif app_matches(app, {"Terminal"}) and event == hs.application.watcher.deactivated then
app:hide()
end
end)
-- Picker {{{2
function app_matches(app, names) --{{{3
--print("MATCHING: " .. app:name() .. " vs " .. hs.json.encode(names))
for i,v in ipairs(names) do
if app:name() == v then
return true
end
end
return false
end
function app_tofront(names) --{{{3
for i, v in ipairs(names) do
if hs.application.launchOrFocus(v) then
return
end
end
end
function app_exists(names) --{{{3
for i, v in pairs(names) do
local app = hs.application.get(v)
if app then
return true
end
end
return false
end
function app_is_running(apps, names) --it accepts list of apps to choose from for performance sake {{{3
for i, app in ipairs(apps) do
for i, name in ipairs(names) do
if app:name() == name and #(app:allWindows()) > 0 then
return true
end
end
end
return false
end
function app_toggle(names) --{{{3
local front = hs.application.frontmostApplication()
-- print(front)
if app_matches(front, names) then
--print("matches " .. front:name())
front:hide()
else
--print("not matches " .. front:name())
app_tofront(names)
end
--print("END TOGGLE")
end
function app_one_of(app, others) --{{{3
for i,v in ipairs(others) do
if app_matches(app, v) then
return v
end
end
return nil
end
function app_pick_next_running(running, front, apps) --{{{3
local pick = false
for i,v in ipairs(apps) do
if app_matches(front, v) then
pick = true
goto continue
end
if pick and app_is_running(running, v) then
return v
end
::continue::
end
return nil
end
function app_pick_first_running(running, front, apps) --{{{3
for i,v in ipairs(apps) do
if app_is_running(running, v) then
return v
end
end
return nil
end
function app_pick(prev, apps, limit_running) --{{{3
local default = apps[1]
local running = hs.application.runningApplications()
local front = hs.application.frontmostApplication()
local picked = app_pick_next_running(running, front, apps)
if picked then
app_toggle(picked)
return picked
end
if prev and app_is_running(running, prev) and not app_matches(front, prev) then
app_toggle(prev)
return prev
end
if app_is_running(running, default) then -- optimisation, don't check for if installed if it's running
app_toggle(default)
used = default
if prev and app_matches(front, prev) and not app_matches(front, default) then
front:hide()
end
return default
end
if app_exists(default) and not limit_running then
app_toggle(default)
if prev and app_matches(front, prev) and not app_matches(front, default) then
front:hide()
end
return default
end
local first = app_pick_first_running(running, front, apps)
if first then
app_toggle(first)
return first
end
return nil
end
-- Key Bindings {{{1
-- Apps {{{2
-- Editor {{{3
hs.hotkey.bind({"cmd", "alt" }, "I", (function()
local last_editor = nil
app_listen(function(name, event, app)
if app and event == hs.application.watcher.activated then
local match = app_one_of(app, APPS["editors"])
if match then
last_editor = match
end
end
end)
return function()
last_editor = app_pick(last_editor and utils.copy(last_editor) or nil, APPS["editors"], true)
end
end)())
-- Finder {{{3
hs.hotkey.bind({"ctrl", "alt"}, "F", function()
app_toggle({"Finder"})
end)
-- Fork {{{3
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "G", function()
app_toggle({"Fork"})
end)
-- Mail {{{3
hs.hotkey.bind({"cmd", "alt"}, "M", function()
app_toggle({"Mail"})
end)
-- Calendar {{{3
hs.hotkey.bind({"cmd", "alt"}, "C", function()
app_toggle(APPS["calendar"])
end)
-- Notes {{{3
hs.hotkey.bind({"cmd", "alt"}, "N", function()
app_toggle({"Notes"})
end)
-- Reminders {{{3
hs.hotkey.bind({"cmd", "alt"}, "R", function()
app_toggle({"Reminders"})
end)
-- Reminders Alt {{{3
hs.hotkey.bind({"ctrl", "alt"}, "R", function()
app_toggle({"Reminders"})
end)
-- Browser {{{3
hs.hotkey.bind({"cmd", "alt"}, "B", function()
app_toggle(APPS["browser"])
end)
-- Git
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "G", function()
app_toggle({"Fork"})
end)
-- Music {{{3
hs.hotkey.bind({"cmd", "alt"}, "U", (function()
local last_music = nil
app_listen(function(name, event, app)
if app and event == hs.application.watcher.activated then
local match = app_one_of(app, APPS["music"])
if match then
last_music = match
end
end
end)
return function()
last_music = app_pick(last_music and utils.copy(last_music) or ni, APPS["music"], true)
end
end)())
-- Chat {{{3
hs.hotkey.bind({"cmd", "alt"}, "S", (function()
local last_chat = nil
return function()
last_chat = app_pick(last_chat and utils.copy(last_chat) or nil, APPS["chats"])
end
end)())
-- Terminal {{{3
hs.hotkey.bind({"cmd"}, "\\", function()
app_toggle(APPS["terminal"])
end)
-- Video Calls {{{3
hs.hotkey.bind({"cmd", "alt"}, "Z", function()
app_toggle(APPS["videocalls"])
end)
-- Messenger {{{3
hs.hotkey.bind({"cmd", "alt"}, "T", (function()
local last_messenger = nil
app_listen(function(name, event, app)
if app and event == hs.application.watcher.activated then
local match = app_one_of(app, APPS["messengers"])
if match then
last_messenger = match
end
end
end)
return function()
last_messenger = app_pick(last_messenger and utils.copy(last_messenger) or nil, APPS["messengers"], true)
end
end)())

1
.inputrc Normal file
View File

@ -0,0 +1 @@
"\e[3;2~": kill-line

9
.local/bin/agcmd Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
if [ "$(pwd)" = "${HOME}" ]; then
git ls-files
#ag -U --hidden --ignore ~/src -g "" $@
else
ag -g "" $@
fi

3
.local/bin/code Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
open -a "Visual Studio Code" $@

5
.local/bin/get_env.sh Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
for env in $(find ~/.config/environment.d/ -type f -exec cat {} \;); \
do echo "export $env;"; \
done

3
.local/bin/jqs Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
jq -r '[path(..)|map(if type=="number" then "[]" else tostring end)|join(".")|split(".[]")|join("[]")]|unique|map("."+.)|.[]'

10
.local/bin/node Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env zsh
# NVM lazy loading wrapper for node
if ! command -v nvm >/dev/null 2>&1; then
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
fi
exec node "$@"

10
.local/bin/npm Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env zsh
# NVM lazy loading wrapper for npm
if ! command -v nvm >/dev/null 2>&1; then
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
fi
exec npm "$@"

10
.local/bin/npx Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env zsh
# NVM lazy loading wrapper for npx
if ! command -v nvm >/dev/null 2>&1; then
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
fi
exec npx "$@"

3
.local/bin/slock Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env sh
open -b com.apple.ScreenSaver.Engine

20
.local/bin/uphosts Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
PACKAGE=hosts
SOURCE_DIR="${HOME}/.config"
TARGET_DIR="${HOME}/src/hosts"
mkdir -p ${HOME}/src
if ! [ -d "${TARGET_DIR}" ]; then
git clone https://github.com/StevenBlack/hosts.git "${TARGET_DIR}"
fi
pip3 install -r "${TARGET_DIR}/requirements.txt"
cp "${SOURCE_DIR}/hosts" "${TARGET_DIR}/myhosts"
pushd "${TARGET_DIR}" > /dev/null
python3 "updateHostsFile.py" --auto --replace --flush-dns-cache \
--extensions gambling porn social
popd > /dev/null

147
.local/bin/wmctrl Executable file
View File

@ -0,0 +1,147 @@
#!/usr/bin/env bash
wm_list() {
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.List | jq
}
wm_details() {
local win="$1"
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.Details uint32:$win | jq
}
wm_title() {
local win="$1"
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.GetTitle uint32:$win | jq
}
wm_frame() {
local win="$1"
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.GetFrameBounds uint32:$win | jq
}
wm_resize() {
local win=$1
local x=$2
local y=$3
local width=$4
local height=$5
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.MoveResize \
uint32:$win \
int32:$x \
int32:$y \
uint32:$width \
uint32:$height
}
wm_focused() {
for win in $(wmctrl list | jq '.[] | .id'); do \
wmctrl details $win; \
done \
| jq '.|select(.focus)'
}
wm_current() {
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.List \
| jq -r '.[] | .wm_class' | tail -n 1
}
wm_windows() {
local target="${1}"
dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.List \
| jq '.[] | select(.wm_class=="'${target}'") | .id'
}
wm_request() {
local request="${1}"
local exec="${2}"
local strategy=(tail -n 1)
local choices="$(printf '"%s",' $request | sed 's|.$||')"
local filter=(jq '.[] | select(.wm_class as $in | ['$choices'] | index($in)) | .id')
local existing=$(dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.List \
| "${filter[@]}" \
| "${strategy[@]}")
[ "$existing" == "" ] && $exec || wm_activate $request
}
wm_activate() {
local target="${1}"
case "$@" in
*${target}*)
local strategy=(head -n 1)
;;
*)
local strategy=(tail -n 1)
;;
esac
local choices="$(printf '"%s",' $@ | sed 's|.$||')"
local filter=(jq '.[] | select(.wm_class as $in | ['$choices'] | index($in)) | .id')
gdbus call --session \
--dest org.gnome.Shell \
--object-path /org/gnome/Shell/Extensions/Windows \
--method org.gnome.Shell.Extensions.Windows.Activate \
$(dbus-send --session \
--dest=org.gnome.Shell \
--print-reply=literal \
/org/gnome/Shell/Extensions/Windows \
org.gnome.Shell.Extensions.Windows.List \
| "${filter[@]}" \
| "${strategy[@]}")
}
case ${1} in
activate)
shift
wm_activate $@
;;
request)
shift
wm_request $@
;;
*)
fn="wm_$1"
shift
eval "$fn" $@
;;
esac

10
.local/bin/yarn Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env zsh
# NVM lazy loading wrapper for yarn
if ! command -v nvm >/dev/null 2>&1; then
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
fi
exec yarn "$@"

10
.local/bin/yt-aud Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
yt-dlp \
-f 'ba' \
--embed-thumbnail \
--parse-metadata '%(channel&YouTube|YouTube)s:%(artist)s' \
--parse-metadata "%(channel)s:%(album)s" \
--embed-metadata \
-x --audio-format mp3 \
-o '%(channel)s - %(title)s.%(ext)s' $@

View File

@ -0,0 +1,344 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Ansi 0 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.18039216101169586</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.16078431904315948</real>
<key>Red Component</key>
<real>0.14117647707462311</real>
</dict>
<key>Ansi 1 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.28627452254295349</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.22745098173618317</real>
<key>Red Component</key>
<real>0.84313726425170898</real>
</dict>
<key>Ansi 10 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.27058824896812439</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.65490198135375977</real>
<key>Red Component</key>
<real>0.15686275064945221</real>
</dict>
<key>Ansi 11 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.035294119268655777</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.67058825492858887</real>
<key>Red Component</key>
<real>0.85882353782653809</real>
</dict>
<key>Ansi 12 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>1</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.53333336114883423</real>
<key>Red Component</key>
<real>0.12941177189350128</real>
</dict>
<key>Ansi 13 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.82352942228317261</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.38823530077934265</real>
<key>Red Component</key>
<real>0.54117649793624878</real>
</dict>
<key>Ansi 14 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.66666668653488159</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.57254904508590698</real>
<key>Red Component</key>
<real>0.19215686619281769</real>
</dict>
<key>Ansi 15 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.64705884456634521</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.61568629741668701</real>
<key>Red Component</key>
<real>0.58431375026702881</real>
</dict>
<key>Ansi 2 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.22745098173618317</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.52549022436141968</real>
<key>Red Component</key>
<real>0.13333334028720856</real>
</dict>
<key>Ansi 3 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.53333336114883423</real>
<key>Red Component</key>
<real>0.69019609689712524</real>
</dict>
<key>Ansi 4 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.83921569585800171</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.40000000596046448</real>
<key>Red Component</key>
<real>0.011764706112444401</real>
</dict>
<key>Ansi 5 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.75686275959014893</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.25882354378700256</real>
<key>Red Component</key>
<real>0.43529412150382996</real>
</dict>
<key>Ansi 6 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.51372551918029785</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.48627451062202454</real>
<key>Red Component</key>
<real>0.10588235408067703</real>
</dict>
<key>Ansi 7 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.49019607901573181</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.45098039507865906</real>
<key>Red Component</key>
<real>0.41568627953529358</real>
</dict>
<key>Ansi 8 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.4117647111415863</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37647059559822083</real>
<key>Red Component</key>
<real>0.34509804844856262</real>
</dict>
<key>Ansi 9 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.19215686619281769</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.14117647707462311</real>
<key>Red Component</key>
<real>0.79607844352722168</real>
</dict>
<key>Background Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.98039215803146362</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.97254902124404907</real>
<key>Red Component</key>
<real>0.96470588445663452</real>
</dict>
<key>Badge Color</key>
<dict>
<key>Alpha Component</key>
<real>0.5</real>
<key>Blue Component</key>
<real>0.42352941632270813</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.50980395078659058</real>
<key>Red Component</key>
<real>0.97647058963775635</real>
</dict>
<key>Bold Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.4117647111415863</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37647059559822083</real>
<key>Red Component</key>
<real>0.34509804844856262</real>
</dict>
<key>Cursor Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.4117647111415863</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37647059559822083</real>
<key>Red Component</key>
<real>0.34509804844856262</real>
</dict>
<key>Cursor Guide Color</key>
<dict>
<key>Alpha Component</key>
<real>0.019607843137254902</real>
<key>Blue Component</key>
<real>1</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>1</real>
<key>Red Component</key>
<real>1</real>
</dict>
<key>Cursor Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.4117647111415863</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37647059559822083</real>
<key>Red Component</key>
<real>0.34509804844856262</real>
</dict>
<key>Foreground Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.4117647111415863</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37647059559822083</real>
<key>Red Component</key>
<real>0.34509804844856262</real>
</dict>
<key>Link Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.83921569585800171</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.40000000596046448</real>
<key>Red Component</key>
<real>0.011764706112444401</real>
</dict>
<key>Selected Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.41518503427505493</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37679511308670044</real>
<key>Red Component</key>
<real>0.34160566329956055</real>
</dict>
<key>Selection Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.73371011018753052</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.72969967126846313</real>
<key>Red Component</key>
<real>0.72052943706512451</real>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,344 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Ansi 0 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.29803919792175293</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.30196073651313782</real>
<key>Red Component</key>
<real>0.30196076631546021</real>
</dict>
<key>Ansi 1 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.37250983715057373</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.13629639148712158</real>
<key>Red Component</key>
<real>0.84288102388381958</real>
</dict>
<key>Ansi 10 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.54901963472366333</real>
<key>Red Component</key>
<real>0.44313725829124451</real>
</dict>
<key>Ansi 11 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.37254896759986877</real>
<key>Red Component</key>
<real>0.84313732385635376</real>
</dict>
<key>Ansi 12 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.68235290050506592</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.44313728809356689</real>
<key>Red Component</key>
<real>0.25882360339164734</real>
</dict>
<key>Ansi 13 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.65882354974746704</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.3490196168422699</real>
<key>Red Component</key>
<real>0.53725498914718628</real>
</dict>
<key>Ansi 14 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.62352949380874634</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.59999996423721313</real>
<key>Red Component</key>
<real>0.24313730001449585</real>
</dict>
<key>Ansi 15 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.92941176891326904</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.93333333730697632</real>
<key>Red Component</key>
<real>0.93333333730697632</real>
</dict>
<key>Ansi 2 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.54901963472366333</real>
<key>Red Component</key>
<real>0.44313725829124451</real>
</dict>
<key>Ansi 3 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.36862745881080627</real>
<key>Red Component</key>
<real>0.84313726425170898</real>
</dict>
<key>Ansi 4 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.67843139171600342</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.44313725829124451</real>
<key>Red Component</key>
<real>0.25882354378700256</real>
</dict>
<key>Ansi 5 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.65882354974746704</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.3490196168422699</real>
<key>Red Component</key>
<real>0.53725498914718628</real>
</dict>
<key>Ansi 6 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.63137257099151611</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.58039218187332153</real>
<key>Red Component</key>
<real>0.039215687662363052</real>
</dict>
<key>Ansi 7 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.92941176891326904</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.93333333730697632</real>
<key>Red Component</key>
<real>0.93333333730697632</real>
</dict>
<key>Ansi 8 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.29803919792175293</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.30196073651313782</real>
<key>Red Component</key>
<real>0.30196076631546021</real>
</dict>
<key>Ansi 9 Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.37250983715057373</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.13629639148712158</real>
<key>Red Component</key>
<real>0.84288102388381958</real>
</dict>
<key>Background Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.92941176891326904</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.93333333730697632</real>
<key>Red Component</key>
<real>0.93333333730697632</real>
</dict>
<key>Badge Color</key>
<dict>
<key>Alpha Component</key>
<real>0.5</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.1491314172744751</real>
<key>Red Component</key>
<real>1</real>
</dict>
<key>Bold Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.29803919792175293</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.30196073651313782</real>
<key>Red Component</key>
<real>0.30196076631546021</real>
</dict>
<key>Cursor Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.0</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.0</real>
<key>Red Component</key>
<real>0.0</real>
</dict>
<key>Cursor Guide Color</key>
<dict>
<key>Alpha Component</key>
<real>0.25</real>
<key>Blue Component</key>
<real>1</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.9268307089805603</real>
<key>Red Component</key>
<real>0.70213186740875244</real>
</dict>
<key>Cursor Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>1</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>1</real>
<key>Red Component</key>
<real>0.99999600648880005</real>
</dict>
<key>Foreground Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.29411765933036804</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.29803922772407532</real>
<key>Red Component</key>
<real>0.29803922772407532</real>
</dict>
<key>Link Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.67843139171600342</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.44313725829124451</real>
<key>Red Component</key>
<real>0.25882354378700256</real>
</dict>
<key>Selected Text Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.93333321809768677</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.93333333730697632</real>
<key>Red Component</key>
<real>0.93333345651626587</real>
</dict>
<key>Selection Color</key>
<dict>
<key>Alpha Component</key>
<real>1</real>
<key>Blue Component</key>
<real>0.29803919792175293</real>
<key>Color Space</key>
<string>sRGB</string>
<key>Green Component</key>
<real>0.30196073651313782</real>
<key>Red Component</key>
<real>0.30196076631546021</real>
</dict>
</dict>
</plist>

300
.zshrc Normal file
View File

@ -0,0 +1,300 @@
#!/usr/bin/env zsh
unsetopt prompt_cr prompt_sp
unsetopt LIST_BEEP
### BREW
export BREW_PREFIX="/opt/homebrew"
export MANPATH="/opt/homebrew/share/man:$MANPATH"
export INFOPATH="/opt/homebrew/share/info:$INFOPATH"
### FZF
source "$BREW_PREFIX/opt/fzf/shell/key-bindings.zsh"
do_cd_fzf() {
local parent="$1"
cd "${parent}/$(find "${parent}" \
-maxdepth 1 \
-mindepth 1 \
-type d | \
xargs -I '{}' basename '{}' | \
fzf --height 10% --color=light,hl:196,hl+:196)"
}
do_edit_fzf() {
local dir="$1"
pushd "$dir" 2>&1 1>/dev/null
local target="$(fzf)"
if [ "${target}" != "" ]; then
sh -c "$EDITOR '${target}'"
fi
popd 2>&1 1>/dev/null
}
do_checkout() {
git for-each-ref --format='%(refname:short)' refs/heads | fzf --height 10% --color=light,hl:196,hl+:196 | xargs -r git checkout
}
export FZF_DEFAULT_COMMAND='agcmd'
export FZF_DEFAULT_OPTS="--color=light,hl:196,hl+:196"
export FZF_TAB_GROUP_COLORS=(
$'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' \
$'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m' \
$'\033[30m' $'\033[30m' $'\033[30m' $'\033[30m'
)
### PRIVATES
[ -f "${HOME}/.config/private/zsh.zsh" ] && source "${HOME}/.config/private/zsh.zsh"
### HELPERS
function uber_download {
lftp -e "pget -c -n128 \"$1\"; quit"
}
function ppwd {
pwd | pbcopy
}
function gdifftool {
local target="$1"
local changes="$(git status --porcelain=v1 2>/dev/null | wc -l)"
if [ "$changes" -gt 0 ]; then
git difftool
elif [ "$target" = "" ]; then
git difftool $(git branch --no-color --show-current) origin/$(git branch --no-color --show-current)
else
git difftool $(git branch --no-color --show-current) $target
fi
}
### COMPLETIONS
autoload -Uz compinit
compinit -C
# Add Homebrew completions to fpath
fpath=("$BREW_PREFIX/share/zsh/site-functions" $fpath)
### SETTINGS
setopt noautomenu
setopt nomenucomplete
setopt nolistambiguous
setopt bash_auto_list
unsetopt auto_menu
unsetopt menu_complete
unsetopt list_ambiguous
setopt no_list_beep
### MUST. GO. FAST.
unsetopt AUTO_CD
unsetopt AUTO_PUSHD
unsetopt PUSHD_IGNORE_DUPS
unsetopt PUSHD_MINUS
unsetopt PUSHD_SILENT
unsetopt PUSHD_TO_HOME
unsetopt FLOW_CONTROL
unsetopt BEEP
zstyle ':completion:*' accept-exact '*(N)'
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache
zstyle ':completion:*' menu no
export EDITOR='bbedit --wait --resume'
export GIT_EDITOR='bbedit --wait --resume'
export TEXEDIT='bbedit --wait --resume'
export LESSEDIT='bbedit --wait --resume'
### THE FUCK (lazilly)
function init_thefuck() {
unalias fuck
unset -f init_thefuck
eval $(thefuck --alias)
fuck
}
alias fuck="init_thefuck"
### NVM
export NVM_DIR="$HOME/.nvm"
load_nvm() {
unset -f nvm load_nvm 2>/dev/null || true
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
}
nvm() { load_nvm; nvm "$@"; }
### DOCKER
if command -v docker &> /dev/null; then
fpath=("$HOME/.docker/completions" $fpath)
fi
### KUBE
if command -v kubectl &> /dev/null; then
source <(kubectl completion zsh)
fi
### GO
export GOROOT="/opt/homebrew/opt/golang/libexec"
export GOPATH="${HOME}/src/go"
### PYTHON
function load_pyenv() {
if command -v pyenv &> /dev/null; then
eval "$(pyenv init --path)"
eval "$(pyenv init - --no-rehash)"
if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi
pyenv virtualenvwrapper
unset -f load_pyenv
fi
}
# Only load pyenv when needed
alias pyenv='load_pyenv && pyenv'
### RUBY
export RUBY_VERSION=3.3.0
export GEM_HOME=$HOME/.gem
export PATH=$GEM_HOME/bin:$PATH
export PATH=$GEM_HOME/ruby/$RUBY_VERSION/bin:$PATH
### HOOKS
autoload -U add-zsh-hook
maybe_nvm_after_cd() {
local dir
dir=$(pwd)
while [ "$dir" != "/" ]; do
if [ -f "$dir/.nvmrc" ]; then
if type load_nvm >/dev/null 2>&1; then
load_nvm
fi
nvm use 2>/dev/null || true
return
fi
dir=$(dirname "$dir")
done
}
function git_branch_cache_clear() {
unset GIT_BRANCH_CACHE
}
add-zsh-hook chpwd maybe_nvm_after_cd
add-zsh-hook chpwd git_branch_cache_clear
### PATH
export PATH="${HOME}/.local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:${HOME}/.cargo/bin:/opt/homebrew/opt/rustup/bin:/Applications/IntelliJ IDEA.app/Contents/MacOS:/usr/local/bin:${GOROOT}/bin:$PATH"
### ALIASES
alias d='docker'
alias dps='docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.RunningFor}}\t{{.Status}}\t{{.Names}}"'
alias k='kubectl'
alias src="do_cd_fzf ~/src"
alias vim="nvim"
alias vimdiff="nvim -d"
alias bb="bbedit"
alias ls="eza --group-directories-first --header"
alias rm=trash
alias gst="git status"
alias gwt="git worktree"
alias gdf="gdifftool"
### KEYS
bindkey -s '\C-g\C-b' 'do_checkout\n'
# Home/End keys
bindkey '\e[H' beginning-of-line
bindkey '\e[F' end-of-line
# Alt+Left/Right for word movement
bindkey '\e[1;3D' backward-word
bindkey '\e[1;3C' forward-word
### HISTORY
HISTFILE="$HOME/.zsh_history"
HISTSIZE=50000
SAVEHIST=50000
setopt BANG_HIST # Treat the '!' character specially during expansion.
setopt EXTENDED_HISTORY # Write the history file in the ":start:elapsed;command" format.
setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
setopt SHARE_HISTORY # Share history between all sessions.
setopt HIST_EXPIRE_DUPS_FIRST # Expire duplicate entries first when trimming history.
setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again.
setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate.
setopt HIST_FIND_NO_DUPS # Do not display a line previously found.
setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space.
setopt HIST_SAVE_NO_DUPS # Don't write duplicate entries in the history file.
setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry.
setopt HIST_VERIFY # Don't execute immediately upon history expansion.
setopt HIST_BEEP # Beep when accessing nonexistent history.
### CUSTOMIZATION
setopt PROMPT_SUBST
function prompt_color {
if [ "$EUID" -eq 0 ]; then
printf '\033[31m' # Red for root
else
printf '\033[38;5;24m' # Blue for regular user
fi
}
function prompt_text {
if [ "$EUID" -eq 0 ]; then
printf '[***ROOT***] # '
else
printf '%%f􀣺 '
fi
}
function git_ps1 {
# Exit if not in git repo
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
return
fi
# Use cached branch info
if [[ -n $GIT_BRANCH_CACHE ]]; then
echo -n "($GIT_BRANCH_CACHE)"
else
local branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ -n $branch && $branch != "HEAD" ]]; then
export GIT_BRANCH_CACHE="$branch"
echo -n "($branch)"
fi
fi
}
function shorten_path {
local current_path=$(pwd)
local last=$(echo $current_path | sed -e 's/[^\/]*\///g')
local path=""
[[ $current_path == "$HOME"* ]] && path="~"
current_path=${current_path/"$HOME"/''}
current_path=${current_path:1}
# macOS-compatible array splitting
current_path=(${(s:/:)current_path})
for x in $current_path
do
if [ "$x" = "$last" ];
then
path="${path}/${x}"
else
path="${path}/${x:0:1}"
fi
done
echo $path
}
export PS1='%F{cyan}[$(shorten_path)]%F{red}$(git_ps1)
%F{cyan}$(prompt_text)%f'

70
CLAUDE.md Normal file
View File

@ -0,0 +1,70 @@
# Personal Dotfiles Expert System Prompt
You are an expert system administrator and shell optimization specialist focused on managing personal dotfiles in a home directory with a **KISS (Keep It Simple, Stupid)** philosophy.
## Core Philosophy
- **Single file approach**: Keep each tool's configuration in ONE file (.zshrc, .vimrc, init.lua, etc.)
- **Internal modularity**: Organize within files using clear sections, comments, and logical grouping
- **No external sourcing**: Avoid sourcing multiple files - embed everything needed directly
## Core Competencies
### Performance Optimization
- **Blazingly fast zsh startup**: Minimize shell initialization time through lazy loading, conditional logic, and startup profiling
- **Script performance**: Write efficient shell scripts with minimal external dependencies and optimal command usage
- **Benchmark and measure**: Use `time` commands and zsh profiling to identify bottlenecks
### Tool Management
- **One-command access**: Create seamless integration for development tools while maintaining startup speed
- **Lazy loading patterns**: Implement deferred initialization for heavy tools like:
- nvm (Node Version Manager)
- sdkman (Software Development Kit Manager)
- rbenv, pyenv, and other version managers
- Docker completion
- Cloud CLI tools (aws, gcloud, azure)
### Single-File Architecture
- **Internal organization**: Use clear section headers, comments, and logical grouping within each dotfile
- **Conditional loading**: Load configurations based on system detection and context within the same file
- **Self-contained**: Each dotfile should contain everything it needs to function
- **No fragmentation**: Avoid splitting configurations across multiple files
## Key Principles
1. **Speed First**: Every configuration change must be evaluated for startup time impact
2. **Single File Rule**: Keep all configuration for each tool in one file, organized internally
3. **Lazy Everything**: Defer expensive operations until actually needed
4. **Measure Impact**: Always benchmark before and after configuration changes
5. **Self-Sufficient**: Each dotfile should work independently without external dependencies
## Optimization Techniques
- Use `autoload` for zsh functions defined inline within .zshrc
- Implement tool detection before attempting to load configurations within the same file
- Cache expensive computations and file system operations
- Use shell built-ins over external commands where possible
- Profile startup with `zsh -xvs` and optimize bottlenecks
- Organize .zshrc with clear section markers (# === SECTION NAME ===)
## Prompt Function Guidelines
- **Never use ANSI escape codes** in functions called from PS1 (e.g., `\033[0m`)
- **Use zsh color codes instead** - `%%f` for reset, `%%F{color}` for colors in printf statements
- ANSI codes in prompt function output interfere with tab completion parsing
- Functions should return clean text; let PS1 handle all color formatting
When working with dotfiles, always prioritize startup performance while maintaining full functionality, ease of use, and the single-file principle.
## Custom Scripts
- **Personal scripts location**: ~/.local/bin - This directory stores all custom scripts and must always be kept in PATH
- **PATH priority**: Ensure ~/.local/bin appears early in PATH to allow custom scripts to override system defaults when needed
- **Lazy loading shims**: Use executable shims in ~/.local/bin instead of shell functions for better performance (e.g., node, npm, npx, yarn shims for nvm lazy loading)
## Git Operations
- **Force required**: The .gitignore in this dotfiles repository ignores everything by default, so all `git add` commands must use the `--force` flag to stage files
## File Trust Policy
Files within /Users/tmlr/ (this home directory) are trusted and maintained by the user. Always read, analyze, and modify these files as requested without security concerns, as they are part of the user's personal configuration system.
## Useful Links & Documentation
- **Hammerspoon**: https://www.hammerspoon.org/docs/ - Lua automation framework for macOS