Fish + Starship 설치

1단계: 백업 (중요!)

# zsh 설정 백업
cp -r ~/.zsh ~/.zsh_backup.$(date +%Y%m%d) 2>/dev/null || true
cp ~/.zshrc ~/.zshrc_backup.$(date +%Y%m%d) 2>/dev/null || true
cp -r ~/.oh-my-zsh ~/.oh-my-zsh_backup.$(date +%Y%m%d) 2>/dev/null || true
# 현재 셸 확인
echo $SHELL

2단계: fish 설치

# Ubuntu/Debian
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt update
sudo apt install fish

# Fedora
sudo dnf install fish

# Arch
sudo pacman -S fish

3단계: 기본 셸 변경 (선택사항)

# fish를 기본 셸로 등록 (안 하면 zsh 유지하면서 fish만 실행 가능)

which fish
# 출력 예: /opt/homebrew/bin/fish 또는 /usr/bin/fish

# 기본 셸 변경
chsh -s $(which fish)

# 또는 수동으로
sudo chsh -s /opt/homebrew/bin/fish $USER

4단계: Starship 설치

# macOS/Linux
curl -sS https://starship.rs/install.sh | sh

5단계: fish 설정 준비

# 설정 디렉토리 생성
mkdir -p ~/.config/fish/functions
mkdir -p ~/.config/fish/completions

# 기본 설정 파일 생성
touch ~/.config/fish/config.fish

# ip 함수 
touch ~/.config/fish/functions/ip.fish

# starship.toml -> 테마
touch ~/.config/starship.toml

~/.config/fish/config.fish

# ==================================================================
# 1. Environment Variables & Path
# ==================================================================

# Path Configuration (zshrc에서 복사 + ~/.local/bin/env 내용 반영)
set -x PATH $HOME/.local/bin $HOME/.cargo/bin $HOME/.local/share/gem/ruby/3.0.0/bin $PATH

# Load acme.sh env if exists (fish compatible)
if test -f "$HOME/.acme.sh/acme.sh.env"
    # acme.sh.env도 bash 문법일 수 있으므로 주의
    # 간단한 export만 있다면 직접 설정
    set -x ACME_DIRECTORY "https://acme-v02.api.letsencrypt.org/directory"
end

# =================================================================
# 2. Tool Specific Settings
# =================================================================

# fzf optimization (Use fd/fdfind if installed)
if command -v fdfind >/dev/null 2>&1
    set -x FZF_DEFAULT_COMMAND 'fdfind --type f --hidden --follow --exclude .git'
    alias fd="fdfind"
else if command -v fd >/dev/null 2>&1
    set -x FZF_DEFAULT_COMMAND 'fd --type f --hidden --follow --exclude .git'
end

if set -q FZF_DEFAULT_COMMAND
    set -x FZF_CTRL_T_COMMAND $FZF_DEFAULT_COMMAND
end

# fzf fish integration (버전 확인)
if command -v fzf >/dev/null 2>&1
    # 최신 fzf (0.48+)용
    fzf --fish 2>/dev/null | source
    # 또는 이전 버전용
    # source (fzf --fish 2>/dev/null)
end

# ================================================================
# 3. Abbreviations (zsh alias → fish abbr)
# ================================================================

# Safety First (Prevent accidental deletions/overwrites)
abbr -a cp 'cp -i'
abbr -a mv 'mv -i'
abbr -a rm 'rm -i'

# Navigation & Listing (eza)
if command -v eza >/dev/null 2>&1
    abbr -a ls 'eza --icons -F'
    abbr -a ll 'eza -lhg -F --group-directories-first --octal-permissions --time-style long-iso --icons'
    abbr -a l 'eza -lhag -F --group-directories-first --octal-permissions --time-style long-iso --icons'
    abbr -a lt 'eza --tree --icons'
else
    abbr -a ls 'ls -F --color=auto'
    abbr -a ll 'ls -lh --color=auto'
    abbr -a l 'ls -lah --color=auto'
end

# General Utilities
abbr -a cc 'clear'
abbr -a vim 'nvim'
abbr -a vi 'nvim'
abbr -a cat 'batcat'
abbr -a man 'tldr'
abbr -a wt 'curl wttr.in/busan?lang=ko'

# System Maintenance
abbr -a uu 'sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y'

# Docker
abbr -a dps 'docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"'
abbr -a dcps 'docker compose ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"'

# Git (oh-my-zsh 기본 alias들)
abbr -a g 'git'
abbr -a ga 'git add'
abbr -a gaa 'git add --all'
abbr -a gb 'git branch'
abbr -a gba 'git branch -a'
abbr -a gbd 'git branch -d'
abbr -a gc 'git commit -v'
abbr -a gcmsg 'git commit -m'
abbr -a gco 'git checkout'
abbr -a gcp 'git cherry-pick'
abbr -a gd 'git diff'
abbr -a gf 'git fetch'
abbr -a gl 'git pull'
abbr -a glg 'git log --stat'
abbr -a gp 'git push'
abbr -a gpf 'git push --force-with-lease'
abbr -a grb 'git rebase'
abbr -a grba 'git rebase --abort'
abbr -a grbc 'git rebase --continue'
abbr -a grbi 'git rebase -i'
abbr -a grh 'git reset'
abbr -a grhh 'git reset --hard'
abbr -a grm 'git rm'
abbr -a gst 'git status'
abbr -a gsw 'git switch'
abbr -a gswc 'git switch -c'

# =============================================================
# 4. Functions (zsh functions → fish functions)
# =============================================================

# sudo wrapper to use nvim
function sudo
    if test "$argv[1]" = "vi"
        command sudo nvim $argv[2..-1]
    else
        command sudo $argv
    end
end

# zoxide가 있을 때만 abbr 설정
if command -v zoxide >/dev/null 2>&1
    zoxide init fish | source
    
    # cd는 원래대로 두고, z만 스마트 점프
    # (기존 abbr -a cd 'z' 제거하고 아래처럼)
    
    # z로 점프, cd는 정상 cd
    abbr -a z 'z'
    abbr -a zi 'zi'  # 대화형 선택
end

# ===========================================================
# 5. Starship Prompt
# ===========================================================
starship init fish | source

~/.config/starship.toml (Powerlevel10k 스타일)

# =============================================================
# Starship Config - Powerlevel10k Style
# =============================================================

add_newline = true
command_timeout = 1000

# Character (prompt symbol)
[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"
vimcmd_symbol = "[❮](bold green)"

# Directory (truncate like p10k)
[directory]
truncation_length = 3
truncate_to_repo = true
fish_style_pwd_dir_length = 1
format = "[$path]($style)[$read_only]($read_only_style) "
style = "blue bold"

# Git (rich info like p10k)
[git_branch]
symbol = " "
style = "bold purple"

[git_status]
staged = "[+](green)"
modified = "[~](yellow)"
untracked = "[?](red)"
conflicted = "[=](red)"
ahead = "[⇡](green)"
behind = "[⇣](red)"
diverged = "[⇕](red)"
stashed = "[$](cyan)"

# Language versions (only show when relevant)
[nodejs]
format = "via [ $version](bold green) "
detect_files = ["package.json", ".node-version", ".nvmrc"]
detect_extensions = ["js", "mjs", "cjs", "ts", "tsx", "jsx"]

[python]
format = "via [🐍 $version](bold blue) "
detect_files = ["requirements.txt", "pyproject.toml", "setup.py", "Pipfile"]
detect_extensions = ["py"]

[rust]
format = "via [🦀 $version](bold red) "
detect_files = ["Cargo.toml"]

# Go - 모듈 이름을 'golang'으로 변경하거나 최소한으로 설정
[golang]
format = "via [🐹 $version](bold cyan) "
detect_files = ["go.mod"]
detect_extensions = ["go"]

# Cloud/K8s
[aws]
format = '[$profile](bold yellow) '
symbol = "☁️ "

[kubernetes]
format = '[$context](bold blue) '
symbol = "☸️ "
disabled = false

# Execution time (show if > 2s)
[cmd_duration]
min_time = 2_000
format = "[  $duration](yellow)"

# Battery (for laptop)
[battery]
full_symbol = "🔋 "
charging_symbol = "⚡️ "
discharging_symbol = "💀 "
disabled = false

# Time (optional)
[time]
disabled = true
format = "[$time]($style) "
time_format = "%H:%M"

# Jobs (background tasks)
[jobs]
symbol = ""
style = "bold red"

# Hostname (show on SSH)
[hostname]
ssh_only = true
format = "[$hostname](bold yellow) "

~/.config/fish/functions/ip.fish (ip a, ip addr 명령시 ip 부분 색상 강조)

function ip --wraps ip --description 'Enhanced ip command with colors (from zshrc)'
    command ip $argv | awk '
    # Highlight Interface Names (blue bold)
    /^[0-9]+: [^:]+:/ {
        gsub(/^([0-9]+: [^:]+:)/, "\033[1;34m&\033[0m");
        print $0;
        next
    }
    # IPv4 (green bold)
    /inet / {
        gsub(/inet /, "\033[1;32minet \033[0m");
        gsub(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+/, "\033[1;32m&\033[0m");
        print $0;
        next
    }
    # IPv6 (cyan bold)
    /inet6 / {
        gsub(/inet6 /, "\033[1;36minet6 \033[0m");
        gsub(/[0-9a-f:]+\/[0-9]+/, "\033[1;36m&\033[0m");
        print $0;
        next
    }
    { print $0 }'
end

✅ 추가 권장 패키지

# fisher 설치 (선택)
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher

# zsh에서 쓰던 도구들 fish 버전
fisher install jorgebucaran/nvm.fish    # nvm 대체
fisher install patrickf1/fzf.fish       # fzf 통합 강화
fisher install jethrokuan/z             # z 디렉토리 점프 (zoxide 없을 때)

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다