Compare commits
8
Commits
104b8e2d8d
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
874a823d1e | ||
|
|
cc90b515c6 | ||
|
|
13ffdfdb04 | ||
|
|
67885075d3 | ||
|
|
9ffe78362e | ||
|
|
f5389de7b8 | ||
|
|
9e059859c6 | ||
|
|
6f9e4910bb |
@@ -8,7 +8,7 @@ This is a personal dotfiles repository targeting macOS (Apple Silicon + Intel) a
|
||||
|
||||
Setup is platform-specific and runs from the repo root:
|
||||
|
||||
- **macOS:** `./setup_mac.sh` — brews dependencies, creates a `neovim` virtualenv, then calls `./clone_and_link_mac.sh`. Uses GNU coreutils' `gln` (not `ln`), so coreutils must be installed first.
|
||||
- **macOS:** `./setup_mac.sh` — brews dependencies, installs the latest verified upstream Alacritty release, creates a `neovim` virtualenv, then calls `./clone_and_link_mac.sh`. Uses GNU coreutils' `gln` (not `ln`), so coreutils must be installed first.
|
||||
- **Arch:** `./setup_arch.sh` — pacman deps, then `./clone_and_link.sh` + `./copy_fonts_arch.sh`.
|
||||
- `clone_and_link*.sh` create the symlinks (`~/.zsh`, `~/.zshrc`, `~/.tmux`, `~/.tmux.conf`, `~/.config/nvim`, `~/.config/alacritty`, virtualenvwrapper hooks). `link_config.sh` is a simpler standalone variant.
|
||||
- `general_setup.sh` switches the login shell to zsh and triggers plugin installs.
|
||||
@@ -33,5 +33,5 @@ Practical rule: **edit the `.example` source, not the generated symlink target.*
|
||||
|
||||
## Maintenance
|
||||
|
||||
- `./update_mac.sh` — macOS update runner. Default (no args) runs `--brew-update --cleanup --diagnostics --update-others`; other flags: `--system-update`, `--permission-fix` (strips Caskroom/App quarantine xattrs). Run `./update_mac.sh --help` for the list. `--update-others` also runs `claude --update` and `Codex --update`.
|
||||
- `brew_autoupdate` — sets up scheduled brew auto-updates.
|
||||
- `./update_mac.sh` — macOS update runner. Default (no args) runs `--brew-update --cleanup --diagnostics --update-others`; other flags: `--system-update`, `--permission-fix` (strips Caskroom/App quarantine xattrs). Run `./update_mac.sh --help` for the list. `--update-others` also updates Alacritty from its verified upstream release, then runs `claude --update` and `Codex --update`.
|
||||
- `brew_autoupdate` — runs scheduled brew and Alacritty auto-updates.
|
||||
|
||||
@@ -6,5 +6,6 @@ export HOMEBREW_LOGS='/Users/ising/Library/Logs/Homebrew'
|
||||
export SUDO_ASKPASS='/Users/ising/Library/Application Support/com.github.domt4.homebrew-autoupdate/brew_autoupdate_sudo_gui'
|
||||
defaults export com.apple.dock "/tmp/dock-layout.plist"
|
||||
/bin/date && /opt/homebrew/bin/brew update && /opt/homebrew/bin/brew upgrade --formula -v && /opt/homebrew/bin/brew upgrade --cask -v && /opt/homebrew/bin/brew cleanup && /usr/bin/open -g /opt/homebrew/Library/Taps/homebrew/homebrew-autoupdate/notifier/brew-autoupdate.app
|
||||
/Users/ising/dotfiles/install_alacritty_mac.sh
|
||||
defaults import com.apple.dock "/tmp/dock-layout.plist"
|
||||
killall dock
|
||||
|
||||
Executable
+265
@@ -0,0 +1,265 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly RELEASE_API="https://api.github.com/repos/alacritty/alacritty/releases/latest"
|
||||
readonly APPLICATIONS_DIR="/Applications"
|
||||
readonly APP_NAME="Alacritty.app"
|
||||
|
||||
temp_dir=""
|
||||
mount_point=""
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "$mount_point" && -d "$mount_point" ]]; then
|
||||
hdiutil detach "$mount_point" >/dev/null 2>&1 || true
|
||||
fi
|
||||
if [[ -n "$temp_dir" && -d "$temp_dir" ]]; then
|
||||
rm -rf "$temp_dir"
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
die() {
|
||||
echo "Alacritty update failed: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_command() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
|
||||
}
|
||||
|
||||
app_version() {
|
||||
/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" \
|
||||
"$1/Contents/Info.plist" 2>/dev/null || true
|
||||
}
|
||||
|
||||
version_is_newer() {
|
||||
local left="${1%%-*}"
|
||||
local right="${2%%-*}"
|
||||
local left_major left_minor left_patch
|
||||
local right_major right_minor right_patch
|
||||
|
||||
IFS=. read -r left_major left_minor left_patch <<< "$left"
|
||||
IFS=. read -r right_major right_minor right_patch <<< "$right"
|
||||
|
||||
[[ "$left_major" =~ ^[0-9]+$ && "$left_minor" =~ ^[0-9]+$ && "$left_patch" =~ ^[0-9]+$ ]] || return 1
|
||||
[[ "$right_major" =~ ^[0-9]+$ && "$right_minor" =~ ^[0-9]+$ && "$right_patch" =~ ^[0-9]+$ ]] || return 1
|
||||
|
||||
(( 10#$left_major > 10#$right_major )) && return 0
|
||||
(( 10#$left_major < 10#$right_major )) && return 1
|
||||
(( 10#$left_minor > 10#$right_minor )) && return 0
|
||||
(( 10#$left_minor < 10#$right_minor )) && return 1
|
||||
(( 10#$left_patch > 10#$right_patch ))
|
||||
}
|
||||
|
||||
run_for_applications() {
|
||||
if [[ -w "$APPLICATIONS_DIR" ]]; then
|
||||
"$@"
|
||||
else
|
||||
sudo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
safe_link() {
|
||||
local source="$1"
|
||||
local destination="$2"
|
||||
|
||||
if [[ -e "$destination" && ! -L "$destination" ]]; then
|
||||
die "will not replace non-symlink: $destination"
|
||||
fi
|
||||
ln -sfn "$source" "$destination"
|
||||
}
|
||||
|
||||
assert_linkable() {
|
||||
local destination="$1"
|
||||
|
||||
if [[ -e "$destination" && ! -L "$destination" ]]; then
|
||||
die "will not replace non-symlink: $destination"
|
||||
fi
|
||||
}
|
||||
|
||||
validate_shell_artifacts() {
|
||||
local app="$1"
|
||||
local brew_prefix="$2"
|
||||
local resources="$app/Contents/Resources"
|
||||
local source manpage section
|
||||
|
||||
for source in \
|
||||
"$app/Contents/MacOS/alacritty" \
|
||||
"$resources/completions/alacritty.bash" \
|
||||
"$resources/completions/alacritty.fish" \
|
||||
"$resources/completions/_alacritty" \
|
||||
"$resources/61/alacritty" \
|
||||
"$resources/61/alacritty-direct"; do
|
||||
[[ -f "$source" ]] || die "required artifact is missing: ${source#"$app/"}"
|
||||
done
|
||||
|
||||
assert_linkable "$brew_prefix/bin/alacritty"
|
||||
assert_linkable "$brew_prefix/etc/bash_completion.d/alacritty"
|
||||
assert_linkable "$brew_prefix/share/fish/vendor_completions.d/alacritty.fish"
|
||||
assert_linkable "$brew_prefix/share/zsh/site-functions/_alacritty"
|
||||
assert_linkable "$HOME/.terminfo/61/alacritty"
|
||||
assert_linkable "$HOME/.terminfo/61/alacritty-direct"
|
||||
|
||||
for section in 1 5 7; do
|
||||
for manpage in "$resources"/*."$section".gz; do
|
||||
[[ -e "$manpage" ]] || continue
|
||||
assert_linkable "$brew_prefix/share/man/man$section/${manpage##*/}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
install_shell_artifacts() {
|
||||
local app="$APPLICATIONS_DIR/$APP_NAME"
|
||||
local resources="$app/Contents/Resources"
|
||||
local brew_prefix="$1"
|
||||
local manpage section
|
||||
|
||||
mkdir -p \
|
||||
"$brew_prefix/bin" \
|
||||
"$brew_prefix/etc/bash_completion.d" \
|
||||
"$brew_prefix/share/fish/vendor_completions.d" \
|
||||
"$brew_prefix/share/zsh/site-functions" \
|
||||
"$brew_prefix/share/man/man1" \
|
||||
"$brew_prefix/share/man/man5" \
|
||||
"$brew_prefix/share/man/man7" \
|
||||
"$HOME/.terminfo/61"
|
||||
|
||||
safe_link "$app/Contents/MacOS/alacritty" "$brew_prefix/bin/alacritty"
|
||||
safe_link "$resources/completions/alacritty.bash" "$brew_prefix/etc/bash_completion.d/alacritty"
|
||||
safe_link "$resources/completions/alacritty.fish" "$brew_prefix/share/fish/vendor_completions.d/alacritty.fish"
|
||||
safe_link "$resources/completions/_alacritty" "$brew_prefix/share/zsh/site-functions/_alacritty"
|
||||
safe_link "$resources/61/alacritty" "$HOME/.terminfo/61/alacritty"
|
||||
safe_link "$resources/61/alacritty-direct" "$HOME/.terminfo/61/alacritty-direct"
|
||||
|
||||
for section in 1 5 7; do
|
||||
for manpage in "$resources"/*."$section".gz; do
|
||||
[[ -e "$manpage" ]] || continue
|
||||
safe_link "$manpage" "$brew_prefix/share/man/man$section/${manpage##*/}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
restore_previous_app() {
|
||||
local destination="$1"
|
||||
local backup="$2"
|
||||
|
||||
run_for_applications rm -rf "$destination"
|
||||
if [[ -d "$backup" ]]; then
|
||||
run_for_applications /usr/bin/ditto "$backup" "$destination"
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local destination="$APPLICATIONS_DIR/$APP_NAME"
|
||||
local release_json latest_tag latest_version asset_name asset_url asset_digest
|
||||
local expected_sha actual_sha dmg staged_app staged_version installed_version
|
||||
local previous_app brew_prefix brew_managed=false
|
||||
|
||||
[[ "$(uname -s)" == "Darwin" ]] || die "this installer only supports macOS"
|
||||
|
||||
require_command brew
|
||||
require_command curl
|
||||
require_command jq
|
||||
require_command hdiutil
|
||||
require_command codesign
|
||||
|
||||
brew_prefix="$(brew --prefix)"
|
||||
if brew list --cask alacritty >/dev/null 2>&1; then
|
||||
brew_managed=true
|
||||
fi
|
||||
|
||||
temp_dir="$(mktemp -d "${TMPDIR:-/tmp}/alacritty-update.XXXXXX")"
|
||||
release_json="$temp_dir/release.json"
|
||||
|
||||
curl --fail --location --silent --show-error --retry 3 \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"$RELEASE_API" -o "$release_json"
|
||||
|
||||
latest_tag="$(jq -er '.tag_name' "$release_json")"
|
||||
latest_version="${latest_tag#v}"
|
||||
asset_name="Alacritty-${latest_tag}.dmg"
|
||||
asset_url="$(jq -er --arg asset "$asset_name" \
|
||||
'.assets[] | select(.name == $asset) | .browser_download_url' "$release_json")"
|
||||
asset_digest="$(jq -er --arg asset "$asset_name" \
|
||||
'.assets[] | select(.name == $asset) | .digest' "$release_json")"
|
||||
|
||||
[[ "$asset_digest" == sha256:* ]] || die "GitHub did not provide a SHA-256 digest for $asset_name"
|
||||
expected_sha="$(printf '%s' "${asset_digest#sha256:}" | tr '[:upper:]' '[:lower:]')"
|
||||
[[ "$expected_sha" =~ ^[[:xdigit:]]{64}$ ]] || die "invalid SHA-256 digest for $asset_name"
|
||||
|
||||
installed_version=""
|
||||
if [[ -d "$destination" ]]; then
|
||||
installed_version="$(app_version "$destination")"
|
||||
fi
|
||||
|
||||
if [[ "$installed_version" == "$latest_version" && "$brew_managed" == false ]]; then
|
||||
validate_shell_artifacts "$destination" "$brew_prefix"
|
||||
install_shell_artifacts "$brew_prefix"
|
||||
echo "Alacritty $installed_version is already up to date."
|
||||
return
|
||||
fi
|
||||
if [[ -n "$installed_version" ]] && version_is_newer "$installed_version" "$latest_version"; then
|
||||
echo "Installed Alacritty $installed_version is newer than stable $latest_version; leaving it unchanged."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Installing Alacritty $latest_version from the upstream release."
|
||||
dmg="$temp_dir/$asset_name"
|
||||
curl --fail --location --silent --show-error --retry 3 "$asset_url" -o "$dmg"
|
||||
|
||||
actual_sha="$(shasum -a 256 "$dmg" | awk '{print $1}')"
|
||||
[[ "$actual_sha" == "$expected_sha" ]] || die "SHA-256 mismatch for $asset_name"
|
||||
|
||||
mount_point="$temp_dir/mount"
|
||||
mkdir -p "$mount_point"
|
||||
hdiutil attach "$dmg" -nobrowse -readonly -mountpoint "$mount_point" >/dev/null
|
||||
[[ -d "$mount_point/$APP_NAME" ]] || die "$APP_NAME is missing from $asset_name"
|
||||
|
||||
staged_app="$temp_dir/$APP_NAME"
|
||||
/usr/bin/ditto "$mount_point/$APP_NAME" "$staged_app"
|
||||
hdiutil detach "$mount_point" >/dev/null
|
||||
mount_point=""
|
||||
|
||||
staged_version="$(app_version "$staged_app")"
|
||||
[[ "$staged_version" == "$latest_version" ]] || die "release metadata says $latest_version, app says $staged_version"
|
||||
codesign --verify --deep --strict "$staged_app" || die "the staged app has an invalid ad-hoc signature"
|
||||
xattr -dr com.apple.quarantine "$staged_app" 2>/dev/null || true
|
||||
validate_shell_artifacts "$staged_app" "$brew_prefix"
|
||||
|
||||
previous_app="$temp_dir/previous/$APP_NAME"
|
||||
if [[ -d "$destination" ]]; then
|
||||
mkdir -p "${previous_app%/*}"
|
||||
/usr/bin/ditto "$destination" "$previous_app"
|
||||
fi
|
||||
|
||||
if [[ "$brew_managed" == true ]]; then
|
||||
echo "Migrating Alacritty away from the disabled Homebrew cask."
|
||||
if ! brew uninstall --cask alacritty; then
|
||||
restore_previous_app "$destination" "$previous_app"
|
||||
install_shell_artifacts "$brew_prefix" || true
|
||||
die "Homebrew could not uninstall its Alacritty cask"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! run_for_applications rm -rf "$destination" || \
|
||||
! run_for_applications /usr/bin/ditto "$staged_app" "$destination"; then
|
||||
restore_previous_app "$destination" "$previous_app"
|
||||
die "could not install $destination"
|
||||
fi
|
||||
|
||||
if ! codesign --verify --deep --strict "$destination" || \
|
||||
[[ "$(app_version "$destination")" != "$latest_version" ]]; then
|
||||
restore_previous_app "$destination" "$previous_app"
|
||||
die "installed app validation failed; restored the previous app"
|
||||
fi
|
||||
|
||||
install_shell_artifacts "$brew_prefix"
|
||||
echo "Alacritty $latest_version installed successfully."
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
+130
-3
@@ -32,9 +32,6 @@ let g:loaded_perl_provider = 0
|
||||
call plug#begin()
|
||||
|
||||
if !exists('g:vscode')
|
||||
" Warn about plugin updates
|
||||
Plug 'semanser/vim-outdated-plugins'
|
||||
|
||||
" Powerline replacement
|
||||
Plug 'vim-airline/vim-airline'
|
||||
Plug 'vim-airline/vim-airline-themes'
|
||||
@@ -112,6 +109,136 @@ endif
|
||||
|
||||
call plug#end()
|
||||
|
||||
" Check for plugin updates after the editor is responsive.
|
||||
lua << EOF
|
||||
local function check_plugin_updates()
|
||||
local plugins = {}
|
||||
for name, plugin in pairs(vim.g.plugs or {}) do
|
||||
if vim.fn.isdirectory(plugin.dir) == 1 then
|
||||
table.insert(plugins, { name = name, dir = plugin.dir })
|
||||
end
|
||||
end
|
||||
table.sort(plugins, function(a, b) return a.name < b.name end)
|
||||
|
||||
local next_plugin = 1
|
||||
local active = 0
|
||||
local finished = 0
|
||||
local failures = 0
|
||||
local updates = {}
|
||||
local concurrency = 2
|
||||
|
||||
local function git_command(args)
|
||||
local command = {}
|
||||
if vim.fn.executable('ionice') == 1 then
|
||||
vim.list_extend(command, { 'ionice', '-c', '3' })
|
||||
end
|
||||
if vim.fn.executable('nice') == 1 then
|
||||
vim.list_extend(command, { 'nice', '-n', '10' })
|
||||
end
|
||||
table.insert(command, 'git')
|
||||
vim.list_extend(command, args)
|
||||
return command
|
||||
end
|
||||
|
||||
local function set_airline_status(message)
|
||||
vim.g.plugin_update_status = message
|
||||
local marker = '%{get(g:,"plugin_update_status","")}'
|
||||
local warning = vim.g.airline_section_warning or ''
|
||||
if not string.find(warning, 'plugin_update_status', 1, true) then
|
||||
vim.g.airline_section_warning = warning .. ' ' .. marker
|
||||
end
|
||||
if vim.fn.exists(':AirlineRefresh') == 2 then
|
||||
vim.cmd('AirlineRefresh')
|
||||
end
|
||||
end
|
||||
|
||||
local function report()
|
||||
if #updates > 0 then
|
||||
set_airline_status(string.format('[updates: %d]', #updates))
|
||||
local message = string.format(
|
||||
'%d plugin update%s available: %s',
|
||||
#updates,
|
||||
#updates == 1 and '' or 's',
|
||||
table.concat(updates, ', ')
|
||||
)
|
||||
if failures > 0 then
|
||||
message = message .. string.format(' (%d check%s failed)', failures, failures == 1 and '' or 's')
|
||||
end
|
||||
vim.notify(message, failures > 0 and vim.log.levels.WARN or vim.log.levels.INFO)
|
||||
elseif failures > 0 then
|
||||
set_airline_status('[update check failed]')
|
||||
vim.notify(
|
||||
string.format('Plugin update check incomplete: %d check%s failed', failures, failures == 1 and '' or 's'),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
else
|
||||
set_airline_status('')
|
||||
vim.notify('All plugins up-to-date', vim.log.levels.INFO)
|
||||
end
|
||||
end
|
||||
|
||||
local pump
|
||||
local function complete_one()
|
||||
active = active - 1
|
||||
finished = finished + 1
|
||||
if finished == #plugins then
|
||||
report()
|
||||
else
|
||||
pump()
|
||||
end
|
||||
end
|
||||
|
||||
local function check_one(plugin)
|
||||
active = active + 1
|
||||
vim.system(
|
||||
git_command({ '-C', plugin.dir, 'fetch', '--quiet', '--no-tags', 'origin' }),
|
||||
{ text = true, timeout = 20000 },
|
||||
vim.schedule_wrap(function(fetch_result)
|
||||
if fetch_result.code ~= 0 then
|
||||
failures = failures + 1
|
||||
complete_one()
|
||||
return
|
||||
end
|
||||
|
||||
vim.system(
|
||||
git_command({ '-C', plugin.dir, 'rev-list', '--count', 'HEAD..@{upstream}' }),
|
||||
{ text = true, timeout = 5000 },
|
||||
vim.schedule_wrap(function(count_result)
|
||||
local count = tonumber(vim.trim(count_result.stdout or ''))
|
||||
if count_result.code ~= 0 or count == nil then
|
||||
failures = failures + 1
|
||||
elseif count > 0 then
|
||||
table.insert(updates, plugin.name)
|
||||
end
|
||||
complete_one()
|
||||
end)
|
||||
)
|
||||
end)
|
||||
)
|
||||
end
|
||||
|
||||
pump = function()
|
||||
while active < concurrency and next_plugin <= #plugins do
|
||||
local plugin = plugins[next_plugin]
|
||||
next_plugin = next_plugin + 1
|
||||
check_one(plugin)
|
||||
end
|
||||
end
|
||||
|
||||
if #plugins > 0 then
|
||||
pump()
|
||||
end
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd('VimEnter', {
|
||||
group = vim.api.nvim_create_augroup('plugin_update_check', { clear = true }),
|
||||
once = true,
|
||||
callback = function()
|
||||
vim.defer_fn(check_plugin_updates, 1500)
|
||||
end,
|
||||
})
|
||||
EOF
|
||||
|
||||
" Run PlugInstall if there are missing plugins
|
||||
autocmd VimEnter * if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
|
||||
\| PlugInstall --sync | source $MYVIMRC
|
||||
|
||||
+6
-4
@@ -6,14 +6,16 @@
|
||||
# Distributed under terms of the MIT license.
|
||||
#
|
||||
|
||||
brew install neovim tmux alacritty coreutils cmake golang npm virtualenvwrapper
|
||||
source /opt/homebrew/bin/virtualenvwrapper.sh
|
||||
brew install neovim tmux coreutils cmake golang jq npm virtualenvwrapper
|
||||
./install_alacritty_mac.sh
|
||||
BREW_PREFIX="$(brew --prefix)"
|
||||
source "$BREW_PREFIX/bin/virtualenvwrapper.sh"
|
||||
mkvirtualenv neovim
|
||||
pip3 install pynvim
|
||||
npm install -g neovim
|
||||
echo For alacritty to work seemlessly with tmux, we will have to add '/usr/local/bin'\
|
||||
echo For alacritty to work seamlessly with tmux, we will add the Homebrew bin directory\
|
||||
to the path. This will require your root password.
|
||||
sudo launchctl config user path /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
|
||||
sudo launchctl config user path /usr/bin:/bin:/usr/sbin:/sbin:"$BREW_PREFIX/bin":/usr/local/bin
|
||||
cp $PWD/nvim/scheme.vim.template $PWD/nvim/scheme.vim
|
||||
cp $PWD/.config/alacritty/schemes.yml.template $PWD/.config/alacritty/schemes.yml
|
||||
./clone_and_link_mac.sh
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file echoes a bunch of 24-bit color codes
|
||||
# to the terminal to demonstrate its functionality.
|
||||
# The foreground escape sequence is ^[38;2;<r>;<g>;<b>m
|
||||
# The background escape sequence is ^[48;2;<r>;<g>;<b>m
|
||||
# <r> <g> <b> range from 0 to 255 inclusive.
|
||||
# The escape sequence ^[0m returns output to default
|
||||
|
||||
setBackgroundColor()
|
||||
{
|
||||
echo -en "\x1b[48;2;$1;$2;$3""m"
|
||||
}
|
||||
|
||||
resetOutput()
|
||||
{
|
||||
echo -en "\x1b[0m\n"
|
||||
}
|
||||
|
||||
# Gives a color $1/255 % along HSV
|
||||
# Who knows what happens when $1 is outside 0-255
|
||||
# Echoes "$red $green $blue" where
|
||||
# $red $green and $blue are integers
|
||||
# ranging between 0 and 255 inclusive
|
||||
rainbowColor()
|
||||
{
|
||||
let h=$1/43
|
||||
let f=$1-43*$h
|
||||
let t=$f*255/43
|
||||
let q=255-t
|
||||
|
||||
if [ $h -eq 0 ]
|
||||
then
|
||||
echo "255 $t 0"
|
||||
elif [ $h -eq 1 ]
|
||||
then
|
||||
echo "$q 255 0"
|
||||
elif [ $h -eq 2 ]
|
||||
then
|
||||
echo "0 255 $t"
|
||||
elif [ $h -eq 3 ]
|
||||
then
|
||||
echo "0 $q 255"
|
||||
elif [ $h -eq 4 ]
|
||||
then
|
||||
echo "$t 0 255"
|
||||
elif [ $h -eq 5 ]
|
||||
then
|
||||
echo "255 0 $q"
|
||||
else
|
||||
# execution should never reach here
|
||||
echo "0 0 0"
|
||||
fi
|
||||
}
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor $i 0 0
|
||||
echo -en " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor $i 0 0
|
||||
echo -en " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor 0 $i 0
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor 0 $i 0
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor 0 0 $i
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor 0 0 $i
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor `rainbowColor $i`
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor `rainbowColor $i`
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
SCRIPT_SOURCE="${BASH_SOURCE[0]}"
|
||||
while [[ -L "$SCRIPT_SOURCE" ]]; do
|
||||
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_SOURCE")" >/dev/null 2>&1 && pwd)"
|
||||
SCRIPT_SOURCE="$(readlink "$SCRIPT_SOURCE")"
|
||||
[[ "$SCRIPT_SOURCE" != /* ]] && SCRIPT_SOURCE="$SCRIPT_DIR/$SCRIPT_SOURCE"
|
||||
done
|
||||
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_SOURCE")" >/dev/null 2>&1 && pwd)"
|
||||
|
||||
ARCH=`uname -m`
|
||||
if [[ $ARCH == "arm64" ]]; then
|
||||
PREFIX="/opt/homebrew/"
|
||||
@@ -55,6 +63,9 @@ function update_others {
|
||||
echo "Update other stuff"
|
||||
echo "----------"
|
||||
|
||||
echo "-- ALACRITTY"
|
||||
"$SCRIPT_DIR/install_alacritty_mac.sh" || echo "Alacritty update failed." >&2
|
||||
|
||||
if [ -x "$(command -v claude)" ]; then
|
||||
echo "-- CLAUDE"
|
||||
claude --update
|
||||
|
||||
@@ -40,3 +40,5 @@ alias python="python3"
|
||||
# Tahoe 26 WindowServer bug: windows stay interactive but can't be moved by
|
||||
# mouse or API until the window-management daemon is restarted (no logout).
|
||||
alias unstick-windows="killall WindowManager"
|
||||
|
||||
alias resetdns="sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder"
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
source "${ZDOTDIR:-$HOME}/.zsh/lib/updates.zsh"
|
||||
export LC_OSC52=1
|
||||
|
||||
# Completions for tools installed under ~/.local (e.g. tools-repo's safe*
|
||||
# wrappers). Must precede antidote, whose completion plugin runs compinit.
|
||||
fpath=("$HOME/.local/share/zsh/site-functions" $fpath)
|
||||
|
||||
plugins_txt=${ZDOTDIR:-$HOME}/.zsh/.zsh_plugins.txt
|
||||
static_file=${ZDOTDIR:-$HOME}/.cache/zsh/.zsh_plugins.zsh
|
||||
source "${ZDOTDIR:-$HOME}/.zsh/lib/antidote.zsh"
|
||||
|
||||
+69
-2
@@ -21,10 +21,77 @@ alias ls='ls --color=always'
|
||||
alias cgrep='grep --color=always'
|
||||
alias cdiff='git diff --color-words --no-index'
|
||||
|
||||
# Remove the files an archive extracted into the current directory.
|
||||
# Lists what it will delete and asks first; -f skips the prompt, -n dry-runs.
|
||||
# Directories are only removed if they end up empty.
|
||||
delzip() {
|
||||
unzip -Z -1 "$@" | xargs -I{} rm -rf {}
|
||||
emulate -L zsh
|
||||
setopt local_options
|
||||
|
||||
local dry=0 force=0
|
||||
while [[ $1 == -[nf] ]]; do
|
||||
[[ $1 == -n ]] && dry=1 || force=1
|
||||
shift
|
||||
done
|
||||
(( $# )) || { print -ru2 "usage: delzip [-n|-f] <archive.zip>..."; return 2 }
|
||||
|
||||
local zip entry parent
|
||||
local -a entries files dirs
|
||||
for zip in "$@"; do
|
||||
[[ -f $zip ]] || { print -ru2 "delzip: no such file: $zip"; return 1 }
|
||||
entries=("${(f)$(unzip -Z -1 -- $zip)}") || return 1
|
||||
for entry in $entries; do
|
||||
[[ -n $entry ]] || continue
|
||||
# zip-slip guard: never touch anything outside the cwd
|
||||
if [[ $entry == (/|~)* || $entry == (|*/)..(|/*) ]]; then
|
||||
print -ru2 "delzip: refusing unsafe path: $entry"
|
||||
return 1
|
||||
fi
|
||||
[[ $entry == */ ]] && dirs+=(${entry%/}) || files+=($entry)
|
||||
# many archives omit directory entries, so infer them from the
|
||||
# paths as well; unzip creates those dirs regardless
|
||||
parent=${entry%/}
|
||||
while [[ $parent == */* ]]; do
|
||||
parent=${parent%/*}
|
||||
dirs+=($parent)
|
||||
done
|
||||
done
|
||||
done
|
||||
dirs=(${(u)dirs})
|
||||
|
||||
# only keep what is actually on disk, so the list reflects reality;
|
||||
# -L catches broken symlinks, which -e alone misses
|
||||
local -a present
|
||||
present=(); for entry in $files; do [[ -e $entry || -L $entry ]] && present+=($entry); done
|
||||
files=($present)
|
||||
present=(); for entry in $dirs; do [[ -d $entry ]] && present+=($entry); done
|
||||
dirs=($present)
|
||||
|
||||
(( $#files + $#dirs )) || { print -ru2 "delzip: nothing to remove here (already gone?)"; return 1 }
|
||||
|
||||
if (( dry )); then
|
||||
print -rl -- ${files} ${(O)dirs}
|
||||
return 0
|
||||
fi
|
||||
|
||||
if (( ! force )); then
|
||||
[[ -t 0 ]] || { print -ru2 "delzip: not a terminal, use -f to skip the prompt"; return 1 }
|
||||
print -r -- "delzip: remove ${#files} file(s) under ${PWD}:"
|
||||
print -rl -- " "${^files[1,20]}
|
||||
(( $#files > 20 )) && print -r -- " ... and $(( $#files - 20 )) more"
|
||||
(( $#dirs )) && print -r -- "plus ${#dirs} directory/ies, if they end up empty."
|
||||
read -q "?Proceed? [y/N] " || { print -r -- $'\naborted'; return 1 }
|
||||
print
|
||||
fi
|
||||
|
||||
(( $#files )) && rm -f -- $files
|
||||
# deepest first, so parents can empty out; rmdir refuses non-empty dirs
|
||||
for entry in ${(O)dirs}; do
|
||||
[[ -d $entry ]] && rmdir -- $entry 2>/dev/null
|
||||
done
|
||||
return 0
|
||||
}
|
||||
export MITMPROXY_SSLKEYLOGFILE='~/.mitmproxy/sslkeylogfile.txt'
|
||||
export MITMPROXY_SSLKEYLOGFILE="$HOME/.mitmproxy/sslkeylogfile.txt"
|
||||
|
||||
unset ZSH_AUTOSUGGEST_USE_ASYNC
|
||||
export LANG='en_US.UTF-8'
|
||||
|
||||
Reference in New Issue
Block a user