1506 слов
8 минуты
Настройка ZSH

Введение#

В прошлый раз я настраивал Oh My Posh, для того чтобы раскрасить вывод консоли, а в этом посте я расскажу о своём конфигурационном файле для ZSH, который помогает ускорить запуск и повысить удобство работы в терминале. В конфиге настроены автодополнение, подсветка синтаксиса, удобные alias и функции для повседневных задач. Поделюсь основными частями конфига, а также таблицей с командами и их описанием. Сам конфиг возможно будет переписываться с течением времени.

Подготовка#

Клонируем репозиторий с пакетом подсветки синтаксиса в ~/.zsh/zsh-syntax-highlighting

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.zsh/zsh-syntax-highlighting

Клонируем репозиторий с пакетом автодополнения в ~/.zsh/zsh-autosuggestions

git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/zsh-autosuggestions

Устанавливаем bat

sudo apt install bat      # Ubuntu/Debian
brew install bat         # Homebrew

Устанавливаем fzf

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

Устанавливаем fd

sudo apt install fd-find # Ubuntu/Debian
brew install fd         # Homebrew

Так же можно установить nvm

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash

И Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Конфигурационный файл .zshrc#

#!/usr/bin/env zsh

# Ускорение запуска за счёт кэширования compinit
autoload -Uz compinit
if [[ -n ${ZDOTDIR}/.zcompdump(#qN.mh+24) ]]; then
  compinit -d ${ZDOTDIR}/.zcompdump
else
  compinit -C
fi

# Инициализация prompt
autoload -Uz promptinit && promptinit

# История команд
setopt extended_history       # записывать время и длительность команд
setopt hist_expire_dups_first # удалять дубли при переполнении истории
setopt hist_ignore_dups       # игнорировать повторяющиеся команды
setopt hist_ignore_space      # не сохранять команды начинающиеся с пробела
setopt hist_verify            # проверять перед выполнением из истории
setopt share_history          # делиться историей между сессиями
setopt inc_append_history     # добавлять команды в историю сразу

HISTSIZE=5000
SAVEHIST=10000
HISTFILE=~/.zsh_history
HIST_STAMPS="yyyy-mm-dd"

# Исправление опечаток
setopt correct_all

# Навигация по директориям
setopt auto_cd              # переход без cd
setopt auto_pushd           # автоматический pushd
setopt pushd_ignore_dups    # игнорировать дубли в стеке
setopt pushdminus           # инвертировать + и - в pushd

# Использовать emacs keybindings даже если EDITOR указывает vi
bindkey -e

# Современные bindings для навигации
bindkey "^[[1;5D" backward-word    # Ctrl+←
bindkey "^[[1;5C" forward-word     # Ctrl+→
bindkey "^[[H" beginning-of-line   # Home
bindkey "^[[F" end-of-line         # End
bindkey "^[[3~" delete-char        # Del
bindkey "^[[3;5~" kill-word        # Ctrl+Del
bindkey '^H' backward-kill-word    # Ctrl+Backspace
bindkey '^[[Z' reverse-menu-complete # Shift+Tab для обратного автодополнения

# ============================================================
# Алиасы и функции
# ============================================================

# Безопасные алиасы
alias rm="rm -i"
alias cp="cp -i"
alias mv="mv -i"

# Улучшенный ls
alias ls="ls --color=auto --group-directories-first"
alias ll="ls -alFh"
alias la="ls -A"
alias l="ls -CF"
alias lt="ls -ltFh" # сортировка по времени
alias lS="ls -lSFh" # сортировка по размеру

# Быстрый доступ
alias home="cd ~"
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias ~="cd ~"

# Утилиты
alias df="df -h"
alias du="du -h"
alias free="free -h"
alias grep="grep --color=auto"
alias egrep="egrep --color=auto"
alias fgrep="fgrep --color=auto"
alias diff="diff --color=auto"
alias mkdir="mkdir -pv"
alias wget="wget -c"
alias ports="netstat -tulanp"

# Brew
alias brewup="brew update && brew upgrade && brew cleanup"

# Git
alias g="git"
alias ga="git add"
alias gc="git commit -v"
alias gco="git checkout"
alias gd="git diff"
alias gl="git pull"
alias gp="git push"
alias gst="git status"
alias gss="git status -s"

# Функция для создания папки и перехода в неё
mkcd() {
  mkdir -p -- "$1" && cd -P -- "$1" || return
}

# Поиск процесса
psearch() {
  ps aux | grep -i -- "$1" | grep -v grep
}

# Поиск файла
fsearch() {
  find . -type f -iname "*$1*" 2>/dev/null
}

# Извлечение архивов
extract() {
  if [ -f "$1" ]; then
    case "$1" in
      *.tar.bz2) tar xjf "$1" ;;
      *.tar.gz)  tar xzf "$1" ;;
      *.bz2)     bunzip2 "$1" ;;
      *.rar)     unrar x "$1" ;;
      *.gz)      gunzip "$1" ;;
      *.tar)     tar xf "$1" ;;
      *.tbz2)    tar xjf "$1" ;;
      *.tgz)     tar xzf "$1" ;;
      *.zip)     unzip "$1" ;;
      *.Z)       uncompress "$1" ;;
      *.7z)      7z x "$1" ;;
      *)         echo "'$1' cannot be extracted" ;;
    esac
  else
    echo "'$1' is not a valid file"
  fi
}

# Создание tar.gz архива
targz() {
  tar -zcvf "${1%%/}.tar.gz" "${1%%/}/"
}

# Получить публичный IP
myip() {
  curl ifconfig.me
  echo
}

# Показать погоду
weather() {
  curl "wttr.in/${1:-Moscow}?0"
}

# ============================================================
# Комплешн и автодополнение
# ============================================================

# Современная система автодополнения
zstyle ':completion:*' completer _expand _complete _ignored _approximate
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' menu select=2
zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' verbose yes
zstyle ':completion:*:descriptions' format '%F{green}-- %d --%f'
zstyle ':completion:*:messages' format '%F{yellow}-- %d --%f'
zstyle ':completion:*:warnings' format '%F{red}-- no matches found --%f'
zstyle ':completion:*:corrections' format '%F{yellow}-- %d (errors: %e) --%f'

# Автодополнение для kill
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'

# Автодополнение для man
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*:manuals.(^1*)' insert-sections true

# Кэширование автодополнения
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache

# ============================================================
# Цветовая схема и выделение синтаксиса
# ============================================================

# Подсветка синтаксиса
if [ -f "$HOME/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]; then
  source "$HOME/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
  
  typeset -A ZSH_HIGHLIGHT_STYLES
  ZSH_HIGHLIGHT_STYLES[default]='fg=#f8f8f2,bold'
  ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=#ff5555,bold'
  ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=#ff79c6,bold'
  ZSH_HIGHLIGHT_STYLES[alias]='fg=#8be9fd'
  ZSH_HIGHLIGHT_STYLES[builtin]='fg=#50fa7b'
  ZSH_HIGHLIGHT_STYLES[function]='fg=#50fa7b'
  ZSH_HIGHLIGHT_STYLES[command]='fg=#f1fa8c'
  ZSH_HIGHLIGHT_STYLES[precommand]='fg=#8be9fd,underline'
  ZSH_HIGHLIGHT_STYLES[commandseparator]='fg=#ff79c6'
  ZSH_HIGHLIGHT_STYLES[hashed-command]='fg=#bd93f9'
  ZSH_HIGHLIGHT_STYLES[path]='fg=#8be9fd,underline'
  ZSH_HIGHLIGHT_STYLES[path_prefix]='fg=#8be9fd'
  ZSH_HIGHLIGHT_STYLES[globbing]='fg=#ffb86c'
  ZSH_HIGHLIGHT_STYLES[history-expansion]='fg=#bd93f9'
  ZSH_HIGHLIGHT_STYLES[single-hyphen-option]='fg=#ffb86c'
  ZSH_HIGHLIGHT_STYLES[double-hyphen-option]='fg=#ffb86c'
  ZSH_HIGHLIGHT_STYLES[back-quoted-argument]='fg=#bd93f9'
  ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=#f1fa8c'
  ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=#f1fa8c'
  ZSH_HIGHLIGHT_STYLES[dollar-quoted-argument]='fg=#f1fa8c'
  ZSH_HIGHLIGHT_STYLES[redirection]='fg=#ff79c6'
  ZSH_HIGHLIGHT_STYLES[comment]='fg=#6272a4,italic'
fi

# Автодополнение команд
if [ -f "$HOME/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh" ]; then
  source "$HOME/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh"
  
  # Настройки автодополнения
  ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#6272a4"
  ZSH_AUTOSUGGEST_STRATEGY=(history completion)
  ZSH_AUTOSUGGEST_USE_ASYNC=true
  bindkey '^ ' autosuggest-accept
fi

# Цветовая схема LS_COLORS
if [ -x "$(command -v dircolors)" ]; then
  eval "$(dircolors -b)"
  zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
fi

# ============================================================
# Node Version Manager (NVM)
# ============================================================
export NVM_DIR="$HOME/.nvm"
if [ -s "$NVM_DIR/nvm.sh" ]; then
  # Ленивая загрузка NVM для ускорения запуска
  nvm() {
    unset -f nvm
    source "$NVM_DIR/nvm.sh"
    nvm "$@"
  }
  
  # Ленивая загрузка node, npm и npx
  node() {
    unset -f node
    source "$NVM_DIR/nvm.sh"
    node "$@"
  }
  
  npm() {
    unset -f npm
    source "$NVM_DIR/nvm.sh"
    npm "$@"
  }
  
  npx() {
    unset -f npx
    source "$NVM_DIR/nvm.sh"
    npx "$@"
  }
fi

# ============================================================
# Homebrew config (Linuxbrew)
# ============================================================
if [ -x "/home/linuxbrew/.linuxbrew/bin/brew" ]; then
  eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
  
  # Ленивая загрузка brew для ускорения запуска
  brew() {
    unset -f brew
    eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
    brew "$@"
  }
fi

# ============================================================
# Дополнительные настройки
# ============================================================

# Улучшенный less
export LESS="-R -M -i -j5"
export LESS_TERMCAP_mb=$'\E[1;31m'     # начало blink
export LESS_TERMCAP_md=$'\E[1;36m'     # начало bold
export LESS_TERMCAP_me=$'\E[0m'        # конец режима
export LESS_TERMCAP_so=$'\E[01;44;33m' # начало standout-mode
export LESS_TERMCAP_se=$'\E[0m'        # конец standout-mode
export LESS_TERMCAP_us=$'\E[1;32m'     # начало underline
export LESS_TERMCAP_ue=$'\E[0m'        # конец underline

# BAT (лучшая замена cat)
export BAT_THEME="Dracula"
alias cat="bat --paging=never"

# FZF (fuzzy finder)
if [ -f ~/.fzf.zsh ]; then
  source ~/.fzf.zsh
  export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
  export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
  export FZF_DEFAULT_OPTS="--height 40% --layout=reverse --border --preview 'bat --color=always --style=numbers --line-range=:500 {}'"
fi

# Cargo (Rust)
if [ -f "$HOME/.cargo/env" ]; then
  source "$HOME/.cargo/env"
  
  # Ленивая загрузка cargo
  cargo() {
    unset -f cargo
    source "$HOME/.cargo/env"
    cargo "$@"
  }
fi

# oh-my-posh
if command -v oh-my-posh >/dev/null 2>&1; then
  eval "$(oh-my-posh --init --shell zsh --config $HOME/.poshthemes/dracula10k.omp.json)"
fi

# ============================================================
# Финальные настройки
# ============================================================

# Автоматическое обновление конфига
zreload() {
  source ~/.zshrc && echo "ZSH config reloaded!"
}

# Уведомление о завершении долгих команд
if [ -x "$(command -v notify-send)" ]; then
  autoload -Uz add-zsh-hook
  
  long_cmd_exec() {
    local cmd="$1"
    local sec="$2"
    (( sec > 5 )) && notify-send -t 5000 "Command completed" "'$cmd' took $sec seconds"
  }
  
  add-zsh-hook preexec long_cmd_preexec
  add-zsh-hook precmd long_cmd_precmd
fi

# Установка заголовка терминала
autoload -Uz add-zsh-hook

function xterm_title_precmd () {
  print -Pn -- '\e]2;%n@%m:%~\a'
}

function xterm_title_preexec () {
  print -Pn -- '\e]2;%n@%m:%~ %# ' && print -n -- "${(q)1}\a"
}

if [[ "$TERM" == (screen*|xterm*|rxvt*|tmux*|putty*|konsole*) ]]; then
  add-zsh-hook -Uz precmd xterm_title_precmd
  add-zsh-hook -Uz preexec xterm_title_preexec
fi

# ============================================================
# Конец конфигурационного файла
# ============================================================

Таблица команд и их описанием#

КомандаТипОписание
rmaliasБезопасное удаление файлов с подтверждением (rm -i)
cpaliasБезопасное копирование файлов с подтверждением (cp -i)
mvaliasБезопасное перемещение или переименование файлов (mv -i)
lsaliasРасширенный вывод списка файлов с подсветкой и группировкой директорий
llaliasДетальный список файлов (ls -alFh)
laaliasВывод всех файлов, включая скрытые (ls -A)
laliasВывод списка файлов в колонках (ls -CF)
ltaliasСортировка файлов по времени (ls -ltFh)
lSaliasСортировка файлов по размеру (ls -lSFh)
homealiasБыстрый переход в домашнюю директорию (cd ~)
..aliasПереход на уровень выше (cd ..)
aliasПереход на два уровня выше (cd ../..)
aliasПереход на три уровня вверх (cd ../../..)
~aliasПереход в домашнюю директорию (cd ~)
dfaliasОтображение занятого дискового пространства в удобном формате (df -h)
dualiasПоказ занимаемого дискового пространства (du -h)
freealiasОтображение информации о памяти (free -h)
grep, egrep, fgrepaliasПоиск в файлах с подсветкой найденного текста (с опцией —color=auto)
diffaliasСравнение файлов с подсветкой различий (diff —color=auto)
mkdiraliasСоздание директорий с отображением создания (mkdir -pv)
wgetaliasЗагрузка файлов с поддержкой продолжения (wget -c)
portsaliasПросмотр активных портов и процессов (netstat -tulanp)
brewupaliasОбновление Homebrew: обновление, апгрейд и очистка (brew update && brew upgrade && brew cleanup)
g, ga, gc, gco, gd, gl, gp, gst, gssaliasНабор команд для работы с Git (git, git add, git commit -v, git checkout, git diff, git pull, git push, git status, git status -s)
cataliasИспользование bat вместо cat для удобного просмотра файлов (bat —paging=never)
mkcdфункцияСоздаёт директорию (если её нет) и переходит в неё
psearchфункцияПоиск процесса по части имени с использованием ps и grep
fsearchфункцияПоиск файла в текущей директории с учетом регистра (find . -type f -iname "")
extractфункцияАвтоматическое извлечение архивов различных форматов (tar.gz, zip, rar и т.д.)
targzфункцияСоздает tar.gz архив из указанной директории
myipфункцияПолучение публичного IP с помощью curl (ifconfig.me)
weatherфункцияПолучение прогноза погоды с wttr.in (по умолчанию для города Moscow)
zreloadфункцияПерезагружает конфигурацию ZSH (source ~/.zshrc) и выводит уведомление
nvm, node, npm, npx”ленивые” функцииПри первом вызове загружают NVM (source ~/.nvm/nvm.sh), затем выполняется соответствующая команда
brew”ленивая” функцияЛенивое подключение Homebrew: загружает необходимые настройки при первом вызове
cargo”ленивая” функцияЗагружает окружение Cargo при первом вызове, если существует $HOME/.cargo/env
xterm_title_precmd, xterm_title_preexecфункцииУстанавливают заголовок окна терминала до и после выполнения команды соответственно
Настройка ZSH
https://guilliman.ru/posts/zsh_config/
Автор
Herman Guilliman
Опубликовано
2025-04-12
Лицензия
CC BY-NC-SA 4.0