feat: separate updates and manage shell config blocks

This commit is contained in:
叶林立
2026-08-19 00:13:39 +08:00
parent 68490db454
commit 04ad87b54d
6 changed files with 497 additions and 87 deletions
+44 -73
View File
@@ -3,6 +3,14 @@
set -u
SCRIPT_DIR=$(CDPATH=; cd "$(dirname "$0")" && pwd) || exit 1
MANAGED_CONFIG_HELPERS=$SCRIPT_DIR/scripts/managed-config.sh
if [ ! -f "$MANAGED_CONFIG_HELPERS" ]; then
printf '错误: 找不到受管配置辅助脚本:%s\n' "$MANAGED_CONFIG_HELPERS" >&2
exit 1
fi
# shellcheck source=scripts/managed-config.sh
. "$MANAGED_CONFIG_HELPERS"
PACKAGE_SOURCE=${PI_PACKAGE_SOURCE:-git:git@bitbucket.org:siakitem/my-pi.git}
POWERLEVEL10K_PRESET_FILE=$SCRIPT_DIR/config/p10k.zsh
CODEGRAPH_INSTALL_URL=https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh
@@ -12,7 +20,6 @@ POWERLEVEL10K_REPOSITORY=https://github.com/romkatv/powerlevel10k.git
ZSH_AUTOSUGGESTIONS_REPOSITORY=https://github.com/zsh-users/zsh-autosuggestions.git
ZSH_SYNTAX_HIGHLIGHTING_REPOSITORY=https://github.com/zsh-users/zsh-syntax-highlighting.git
install_failed=0
zshrc_backup_done=0
say() {
printf '%s\n' "$*"
@@ -162,6 +169,8 @@ resolve_zsh_paths() {
oh_my_zsh_dir=${ZSH:-$HOME/.oh-my-zsh}
zsh_custom_dir=${ZSH_CUSTOM:-$oh_my_zsh_dir/custom}
zshrc_file=${ZDOTDIR:-$HOME}/.zshrc
my_pi_config_dir=${XDG_CONFIG_HOME:-$HOME/.config}/my-pi
p10k_managed_config_file=$my_pi_config_dir/p10k.zsh
}
oh_my_zsh_installed() {
@@ -190,15 +199,21 @@ prepare_zshrc() {
zshrc_dir=${zshrc_file%/*}
[ "$zshrc_dir" = "$zshrc_file" ] && zshrc_dir=.
mkdir -p "$zshrc_dir" || return 1
if [ ! -f "$zshrc_file" ]; then
: > "$zshrc_file" || return 1
fi
if [ "$zshrc_backup_done" -eq 0 ]; then
zshrc_backup="$zshrc_file.my-pi-backup-$(date +%Y%m%d%H%M%S)"
cp "$zshrc_file" "$zshrc_backup" || return 1
zshrc_backup_done=1
say "已备份现有 Zsh 配置到 $zshrc_backup"
fi
[ -f "$zshrc_file" ] || : > "$zshrc_file" || return 1
}
replace_zsh_managed_block() {
managed_id=$1
managed_placement=$2
managed_anchor=$3
shift 3
managed_content=$(mktemp "${TMPDIR:-/tmp}/my-pi-zsh-block.XXXXXX") || return 1
printf '%s\n' "$@" > "$managed_content"
my_pi_replace_managed_block "$zshrc_file" "$managed_id" "$managed_content" \
"$managed_placement" "$managed_anchor"
managed_status=$?
rm -f "$managed_content"
return "$managed_status"
}
zshrc_has_oh_my_zsh_loader() {
@@ -211,50 +226,26 @@ ensure_oh_my_zsh_loader() {
if zshrc_has_oh_my_zsh_loader; then
return 0
fi
{
printf '\n# Oh My Zsh (managed by my-pi install.sh)\n'
printf 'export ZSH="%s"\n' "$oh_my_zsh_dir"
printf '%s\n' "source \"\$ZSH/oh-my-zsh.sh\""
} >> "$zshrc_file"
replace_zsh_managed_block "oh-my-zsh-loader" "append" "" \
"export ZSH=\"$oh_my_zsh_dir\"" \
"source \"\$ZSH/oh-my-zsh.sh\""
}
set_powerlevel10k_theme() {
prepare_zshrc || return 1
tmp_file=$(mktemp "${TMPDIR:-/tmp}/my-pi-zshrc.XXXXXX") || return 1
if ! awk '
BEGIN { inserted = 0 }
/^[[:space:]]*ZSH_THEME[[:space:]]*=/ { next }
!inserted && /^[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh/ {
print "ZSH_THEME=\"powerlevel10k/powerlevel10k\""
inserted = 1
}
{ print }
END {
if (!inserted) print "ZSH_THEME=\"powerlevel10k/powerlevel10k\""
}
' "$zshrc_file" > "$tmp_file"; then
rm -f "$tmp_file"
return 1
fi
cp "$tmp_file" "$zshrc_file" || {
rm -f "$tmp_file"
return 1
}
rm -f "$tmp_file"
replace_zsh_managed_block "powerlevel10k-theme" "before" \
'^(# >>> my-pi:oh-my-zsh-loader >>>|[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh)' \
'ZSH_THEME="powerlevel10k/powerlevel10k"'
}
p10k_config_sourced() {
[ -f "$zshrc_file" ] || return 1
grep -E '^[[:space:]]*\[\[[[:space:]].*\.p10k\.zsh.*source[[:space:]].*\.p10k\.zsh' \
"$zshrc_file" >/dev/null 2>&1
my_pi_managed_block_exists "$zshrc_file" "powerlevel10k-config"
}
ensure_p10k_config_source() {
if p10k_config_sourced; then
return 0
fi
printf '\n# Powerlevel10k preset (managed by my-pi install.sh)\n[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh\n' \
>> "$zshrc_file"
prepare_zshrc || return 1
replace_zsh_managed_block "powerlevel10k-config" "append" "" \
"[[ ! -f \"$p10k_managed_config_file\" ]] || source \"$p10k_managed_config_file\""
}
configure_powerlevel10k() {
@@ -269,17 +260,11 @@ configure_powerlevel10k() {
git clone --depth=1 "$POWERLEVEL10K_REPOSITORY" "$powerlevel10k_dir" || return 1
fi
if [ ! -f "$HOME/.p10k.zsh" ]; then
if [ ! -f "$POWERLEVEL10K_PRESET_FILE" ]; then
warn "找不到仓库内置的 Powerlevel10k 配置:$POWERLEVEL10K_PRESET_FILE"
return 1
fi
cp "$POWERLEVEL10K_PRESET_FILE" "$HOME/.p10k.zsh" || return 1
say "已写入仓库内置的 Powerlevel10k Rainbow/ASCII 配置,首次启动不会进入配置向导。"
fi
my_pi_sync_managed_file "$POWERLEVEL10K_PRESET_FILE" "$p10k_managed_config_file" || return 1
set_powerlevel10k_theme || return 1
ensure_oh_my_zsh_loader || return 1
ensure_p10k_config_source
ensure_p10k_config_source || return 1
say "已应用仓库内置的 Powerlevel10k Rainbow/ASCII 受管配置。"
}
zsh_plugin_enabled() {
@@ -305,24 +290,9 @@ add_zsh_plugin() {
plugin=$1
prepare_zshrc || return 1
ensure_oh_my_zsh_loader || return 1
tmp_file=$(mktemp "${TMPDIR:-/tmp}/my-pi-zshrc.XXXXXX") || return 1
if ! awk -v plugin="$plugin" '
BEGIN { added = 0 }
!added && /^[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh/ {
print "plugins+=(" plugin ")"
added = 1
}
{ print }
END { if (!added) print "plugins+=(" plugin ")" }
' "$zshrc_file" > "$tmp_file"; then
rm -f "$tmp_file"
return 1
fi
cp "$tmp_file" "$zshrc_file" || {
rm -f "$tmp_file"
return 1
}
rm -f "$tmp_file"
replace_zsh_managed_block "zsh-plugin-$plugin" "before" \
'^(# >>> my-pi:oh-my-zsh-loader >>>|[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh)' \
"plugins+=($plugin)"
}
install_and_enable_zsh_plugin() {
@@ -409,8 +379,9 @@ if [ "$oh_my_zsh_ok" -eq 1 ]; then
resolve_zsh_paths
powerlevel10k_dir=$zsh_custom_dir/themes/powerlevel10k
if [ -f "$powerlevel10k_dir/powerlevel10k.zsh-theme" ] && \
grep -E "^[[:space:]]*ZSH_THEME[[:space:]]*=[[:space:]]*[\"']?powerlevel10k/powerlevel10k[\"']?" \
"$zshrc_file" >/dev/null 2>&1 && [ -f "$HOME/.p10k.zsh" ] && p10k_config_sourced; then
my_pi_managed_block_exists "$zshrc_file" "powerlevel10k-theme" && \
[ -f "$p10k_managed_config_file" ] && \
cmp -s "$POWERLEVEL10K_PRESET_FILE" "$p10k_managed_config_file" && p10k_config_sourced; then
say "✓ Powerlevel10k 已安装并配置"
elif ask_yes_no "Powerlevel10k 尚未完整配置。是否安装并应用仓库内置的 Rainbow/ASCII 配置?"; then
configure_powerlevel10k || record_install_failure "Powerlevel10k"