add zsh
This commit is contained in:
244
airline.zsh
Normal file
244
airline.zsh
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
# ================================
|
||||||
|
# airline.zsh - Modern ZSH Prompt
|
||||||
|
# ================================
|
||||||
|
# Clean, fast powerline-style prompt with ai.moji support
|
||||||
|
# Author: syui
|
||||||
|
# License: MIT
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Core Configuration
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
# Theme colors (256-color palette)
|
||||||
|
typeset -gA AIRLINE_THEME
|
||||||
|
AIRLINE_THEME=(
|
||||||
|
dir_bg 33 # Blue
|
||||||
|
dir_fg 15 # White
|
||||||
|
git_bg 2 # Green
|
||||||
|
git_fg 0 # Black
|
||||||
|
os_bg 5 # Magenta
|
||||||
|
os_fg 15 # White
|
||||||
|
mode_normal 1 # Red
|
||||||
|
mode_insert 6 # Cyan
|
||||||
|
mode_emacs 3 # Yellow
|
||||||
|
)
|
||||||
|
|
||||||
|
# Powerline separators
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
readonly AIRLINE_SEP=""
|
||||||
|
readonly AIRLINE_RSEP=""
|
||||||
|
else
|
||||||
|
readonly AIRLINE_SEP=""
|
||||||
|
readonly AIRLINE_RSEP=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Icon System
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function _airline_setup_icons() {
|
||||||
|
typeset -gA AIRLINE_ICONS
|
||||||
|
|
||||||
|
# Check for ai.moji font
|
||||||
|
# git clone https://git.syui.ai/ai/moji
|
||||||
|
if [[ -f ~/.local/share/fonts/aimoji.ttf ]] || [[ -f ~/.fonts/aimoji.ttf ]]; then
|
||||||
|
# ai.moji icons (placeholder - update when font is ready)
|
||||||
|
AIRLINE_ICONS=(
|
||||||
|
dir ""
|
||||||
|
branch ""
|
||||||
|
staged ""
|
||||||
|
unstaged ""
|
||||||
|
untrack ""
|
||||||
|
clean ""
|
||||||
|
os_mac ""
|
||||||
|
os_arch ""
|
||||||
|
os_linux ""
|
||||||
|
)
|
||||||
|
else
|
||||||
|
# Unicode fallback
|
||||||
|
AIRLINE_ICONS=(
|
||||||
|
dir "📁"
|
||||||
|
branch "🌿"
|
||||||
|
staged "+"
|
||||||
|
unstaged "~"
|
||||||
|
untrack "?"
|
||||||
|
clean "✓"
|
||||||
|
os_mac "🍎"
|
||||||
|
os_arch "🏔️"
|
||||||
|
os_linux "🐧"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS-specific icon
|
||||||
|
case "$OSTYPE" in
|
||||||
|
darwin*)
|
||||||
|
AIRLINE_ICONS[os]="${AIRLINE_ICONS[os_mac]}"
|
||||||
|
;;
|
||||||
|
linux*)
|
||||||
|
if [[ -f /etc/arch-release ]]; then
|
||||||
|
AIRLINE_ICONS[os]="${AIRLINE_ICONS[os_arch]}"
|
||||||
|
else
|
||||||
|
AIRLINE_ICONS[os]="${AIRLINE_ICONS[os_linux]}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AIRLINE_ICONS[os]="💻"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Color Functions
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function _airline_color() {
|
||||||
|
echo "%{\e[38;5;${1}m%}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _airline_bg() {
|
||||||
|
echo "%{\e[48;5;${1}m%}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _airline_reset() {
|
||||||
|
echo "%{\e[0m%}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Segment Builder
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function _airline_segment() {
|
||||||
|
local bg="$1" fg="$2" content="$3" next_bg="${4:-reset}"
|
||||||
|
local out=""
|
||||||
|
|
||||||
|
out+="$(_airline_bg $bg)$(_airline_color $fg) $content "
|
||||||
|
|
||||||
|
if [[ "$next_bg" != "reset" ]]; then
|
||||||
|
out+="$(_airline_bg $next_bg)$(_airline_color $bg)$AIRLINE_SEP"
|
||||||
|
else
|
||||||
|
out+="$(_airline_reset)$(_airline_color $bg)$AIRLINE_SEP$(_airline_reset)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Information Providers
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function _airline_dir() {
|
||||||
|
local content="${AIRLINE_ICONS[dir]} %~"
|
||||||
|
echo "$(_airline_segment ${AIRLINE_THEME[dir_bg]} ${AIRLINE_THEME[dir_fg]} "$content" ${AIRLINE_THEME[git_bg]})"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _airline_git() {
|
||||||
|
# Early return if not in git repo
|
||||||
|
git rev-parse --git-dir >/dev/null 2>&1 || return
|
||||||
|
|
||||||
|
local branch_name content git_status=""
|
||||||
|
branch_name=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null)
|
||||||
|
|
||||||
|
# Get status counts
|
||||||
|
local staged unstaged untracked
|
||||||
|
staged=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
unstaged=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
untracked=$(git ls-files --other --exclude-standard 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
|
||||||
|
# Build status indicator
|
||||||
|
if [[ $staged -gt 0 || $unstaged -gt 0 || $untracked -gt 0 ]]; then
|
||||||
|
[[ $staged -gt 0 ]] && git_status+=" $(_airline_color 15)${AIRLINE_ICONS[staged]}$staged"
|
||||||
|
[[ $unstaged -gt 0 ]] && git_status+=" $(_airline_color 9)${AIRLINE_ICONS[unstaged]}$unstaged"
|
||||||
|
[[ $untracked -gt 0 ]] && git_status+=" $(_airline_color 11)${AIRLINE_ICONS[untrack]}$untracked"
|
||||||
|
git_status+="$(_airline_color ${AIRLINE_THEME[git_fg]})"
|
||||||
|
else
|
||||||
|
git_status=" $(_airline_color 10)${AIRLINE_ICONS[clean]}$(_airline_color ${AIRLINE_THEME[git_fg]})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
content="${AIRLINE_ICONS[branch]} $branch_name$git_status"
|
||||||
|
echo "$(_airline_segment ${AIRLINE_THEME[git_bg]} ${AIRLINE_THEME[git_fg]} "$content" ${AIRLINE_THEME[os_bg]})"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _airline_os() {
|
||||||
|
local content="${AIRLINE_ICONS[os]}"
|
||||||
|
echo "$(_airline_segment ${AIRLINE_THEME[os_bg]} ${AIRLINE_THEME[os_fg]} "$content")"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Vi Mode Indicator
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function _airline_mode() {
|
||||||
|
local mode_bg mode_fg mode_text
|
||||||
|
|
||||||
|
case "${KEYMAP:-main}" in
|
||||||
|
vicmd)
|
||||||
|
mode_bg="${AIRLINE_THEME[mode_normal]}"
|
||||||
|
mode_fg="15"
|
||||||
|
mode_text="NORMAL"
|
||||||
|
;;
|
||||||
|
main|viins)
|
||||||
|
mode_bg="${AIRLINE_THEME[mode_insert]}"
|
||||||
|
mode_fg="0"
|
||||||
|
mode_text="INSERT"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
mode_bg="${AIRLINE_THEME[mode_emacs]}"
|
||||||
|
mode_fg="0"
|
||||||
|
mode_text="EMACS"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "$(_airline_bg $mode_bg)$(_airline_color $mode_fg) $mode_text $(_airline_reset)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Main Prompt Functions
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function airline_prompt() {
|
||||||
|
local segments=""
|
||||||
|
segments+="$(_airline_dir)"
|
||||||
|
segments+="$(_airline_git)"
|
||||||
|
segments+="$(_airline_os)"
|
||||||
|
echo "$segments "
|
||||||
|
}
|
||||||
|
|
||||||
|
function airline_rprompt() {
|
||||||
|
echo "$(_airline_mode)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Setup and Initialization
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
function airline_setup() {
|
||||||
|
# Initialize icons
|
||||||
|
_airline_setup_icons
|
||||||
|
|
||||||
|
# Vi mode setup
|
||||||
|
function zle-keymap-select() {
|
||||||
|
zle reset-prompt
|
||||||
|
}
|
||||||
|
zle -N zle-keymap-select
|
||||||
|
|
||||||
|
# Key bindings
|
||||||
|
bindkey '^E' emacs
|
||||||
|
bindkey '^V' vi-cmd-mode
|
||||||
|
|
||||||
|
# Enable prompt substitution
|
||||||
|
setopt PROMPT_SUBST
|
||||||
|
|
||||||
|
# Set prompts
|
||||||
|
PROMPT='$(airline_prompt)'
|
||||||
|
RPROMPT='$(airline_rprompt)'
|
||||||
|
}
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Auto-initialize
|
||||||
|
# ================================
|
||||||
|
|
||||||
|
# Only setup if being sourced (not in subshell)
|
||||||
|
if [[ "${(%):-%N}" == *airline.zsh ]]; then
|
||||||
|
airline_setup
|
||||||
|
fi
|
Reference in New Issue
Block a user