From 359cabaf5959f4e96a0195b82e702ad36a098805 Mon Sep 17 00:00:00 2001 From: syui Date: Wed, 11 Jun 2025 07:45:20 +0900 Subject: [PATCH] add zsh --- airline.zsh | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 airline.zsh diff --git a/airline.zsh b/airline.zsh new file mode 100644 index 0000000..a1547f6 --- /dev/null +++ b/airline.zsh @@ -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