LINUX.ORG.RU

Переезжаем на Fish

 , ,

Переезжаем на Fish

4

3

Fish — это современный командный интерпретатор, недавно переписанный на Rust, который не требует особой настройки, поддерживая из коробки автодополнение и подсветку синтаксиса. Является лучшим Unix SHELL по версии Slant.

Установка

Установка Fish:

# Arch Linux, Manjaro и тп 
sudo pacman -S fish

# Fedora
sudo dnf install fish

# NixOS
nix-env -i fish

# Ubuntu и остальные Debian-based
sudo add-apt-repository ppa:fish-shell/release-4
sudo apt update
sudo apt install fish

Чтобы сделать fish оболочкой по умолчанию для текущего пользователя:

sudo chsh -s $(which fish) $(whoami)

Прочитайте справку после запуска fish:

help

Fisher — это менеджер плагинов для Fish:

# Из стандартного репозитория Arch
pacman -S fisher

# Вручную
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher

Конфигурация Fish

Основная конфигурация хранится в ~/.config/fish/config.fish:

if not status is-interactive
  exit
end

# Эти пути будут добавлены в $PATH единожды
fish_add_path -m ~/bin ~/.local/bin

# Определим переменные XDG
set -q XDG_DATA_HOME || set -U XDG_DATA_HOME $HOME/.local/share
set -q XDG_STATE_HOME || set -U XDG_STATE_HOME $HOME/.local/state
set -q XDG_CONFIG_HOME || set -U XDG_CONFIG_HOME $HOME/.config
set -q XDG_CACHE_HOME || set -U XDG_CACHE_HOME $HOME/.cache

# Различные настройки
# Используем привычные сочетания клавиш
set -U fish_key_bindings fish_default_key_bindings

# Двойное нажатие ESC не работает, если выставить меньше
set -g fish_escape_delay_ms 300

# В Yakuake вывод fetch не очень смотрится
if command -q fastfetch && ! string match -q -- "*yakuake*" (pstree -s -p $fish_pid)
  fastfetch
end

Настроить fish можно через веб-интерфейс:

fish_config

Отличия Fish от Bash и ZSH

Другой синтаксис

  • Нет $$ и прочих $*.
  • Не нужно экранировать переменные.
  • Нет HEREDOC.
  • Он напоминает Ruby с его end для обозначения окончания блока вместо fi, done, esac и тп.
  • Вместо $(command) нужно писать просто (command).
  • Кроме алиасов есть аббревиатуры, которые при вводе заменяются на полную команду.

Существует множество отличий с которыми лучше ознакомиться, прочитав документацию:

Переменные окружения

Fish использует собственный механизм управления переменными окружения, который отличается от bash и zsh. Основные типы переменных:

  • set VAR value — устанавливает переменную VAR только в текущей сессии.
  • set -x VAR value — делает переменную доступной для дочерних процессов (аналог export в bash).
  • set -gx VAR value — глобальная переменная, доступная во всех сессиях fish.
  • set -Ux VAR value — универсальная переменная, которая сохраняется в ~/.config/fish/fish_variables, те эту команду достаточно ввести в терминале один раз.
  • set -e VAR — удаляет переменную.

Пример установки переменных:

set -x PATH /usr/local/bin $PATH  # Добавляем путь в переменную окружения
set -Ux EDITOR vim                # Устанавливаем универсальную переменную

Для модификации $PATH есть функция fish_path_add:

fish_add_path $HOME/bin $HOME/.local/bin

Это аналогично установке универсальных переменных:

set -U fish_user_paths $HOME/bin $HOME/.local/bin

Темы и оформление

Темы можно ставить как через fisher так и Oh my fish.

Oh my fish содержит ряд адаптированных тем из мегапопулярного Oh my zsh, а так же дополнительно позволяет ставить плагины:

curl -L https://get.oh-my.fish | fish

Поиск тем или пакетов:

omf search [ -t | -p ] name

Список тем:

omf theme

Установка темы:

omf install pure

Смена ее на дефолтную:

omf theme default

Через fisher так же можно ставить темы:

fisher install pure-fish/pure

Плагины в Fish

Работа с плагинами через fisher:

fisher install plugin_name
fisher remove plugin_name
fisher list

Редактирование списка установленных плагинов:

$EDITOR $__fish_config_dir/fish_plugins

Пример плагинов для установки:

Gazorby/fish-abbreviation-tips
PatrickF1/fzf.fish
jethrokuan/z
jorgebucaran/autopair.fish
jorgebucaran/replay.fish
nickeb96/puffer-fish

Популярные плагины, которые можно поставить:

  • Gazorby/fish-abbreviation-tips: показывает подсказки для аббревиатур, помогая запомнить их.

  • PatrickF1/fzf.fish: интеграция fzf для удобного поиска файлов, истории команд и Git-веток.

  • acomagu/fish-async-prompt: асинхронно обновляет промпт. Бажный.

  • franciscolourenco/done: показывает десктопные уведомления о завершении длительных команд.

  • jethrokuan/z: быстрый переход по каталогам с использованием z.

  • jorgebucaran/autopair.fish: автоматическое закрытие скобок.

  • jorgebucaran/replay.fish: позволяет запускать команды Bash (replay ...).

  • joseluisq/gitnow@2.12.0: содержит функции для работы с git.

  • nickeb96/puffer-fish: добавляет привычный многим !! для быстрой подстановки предыдущей команды.

После редактирования списка запускаем обновление плагинов:

fisher update

При установке через fisher install плагины добавляются в тот список в файле, remove — удаляются. Если что-то удалить из него, то при вызове update будут удалены соответствующие плагины.

Ряд плагинов можно поставить через OMF:

omf update  # Обновим Oh my fish
omf install pyenv

omf так же можно использовать как пакетный менеджер

Прочее

Для работы с буфером обмена есть ф-ии fish_clipboard_copy и fish_clipboard_paste.

Автодополнения генерируются прямо из man-файлов:

fish_update_completions

Алиасы можно сохранять прямо из терминала с помощью флага -s:

# Заменим убогий ls на модный ROR-аналог
alias -s ls "eza --icons"

Добавляем sudo к текущей либо предыдущей команде:

function repeat_with_sudo
    # Получаем текущую команду из командной строки
    set -l cmd (commandline)
    
    # Если команда пустая, берём последнюю команду из истории
    if test -z "$cmd"
        set cmd $history[1]
    end
    
    # Заменяем текущую команду на "sudo <команда>"
    commandline -r "sudo $cmd"
end

funcsave repeat_with_sudo

# Это нужно добавить в конфиг
# Привязка к Alt+S
bind \es 'repeat_with_sudo'

# Готовый плагин для Oh my fish
omf install sudope

Переопределяем command not found:

function fish_command_not_found
  # Вместо этой строки нужно какую-то логику реализовать
  __fish_default_command_not_found_handler $argv[1]
end

funcsave fish_command_not_found

В арче, если установлен pkgfile, то все работает из коробки:

~
❯ python2
python2 may be found in the following packages:
  archlinuxcn/python2 2.7.18-12 /usr/bin/python2

Менеджер сниппетов Pet можно интегрировать с fish через плагин otms61/fish-pet:

fisher install otms61/fish-pet

Добавляем сочетание клавиш:

# Сочетания должны храниться в функции
function fish_user_key_bindings
  bind \cs 'pet-select'
end

# Сохраняем сочетания
funcsave fish_user_key_bindings

# Если сочетания заданы, то отредактируйте ф-ию
funced fish_user_key_bindings

Добавление аббревиатур:

abbr -a vimrc 'vim ~/.vim/vimrc'
abbr > ~/.config/fish/conf.d/abbrs.fish

Аббревиатуры заменяются на полные команды.

Заключение

Fish — простой шеллозаменитель для тех, кому лень заморачиваться с настройкой zsh. Он существует достаточно давно, но его фанатская база не является какой-то огромной, пользователи часто пользуются дефолтом, редко меняя шелл.

Что радует:

  • работает заметно быстрее того же zsh;
  • минимум настроек;
  • чистые конфиги;
  • более дружелюбный синтаксис и предсказуемое поведение с попыткой сохранить совместимость в отличии от какого-нибудь марсианского nushell.

Что огорчает:

  • мало плагинов;
  • странные баги, которые вылечить можно только сносом ~/.config/fish;
  • нестандартный синтаксис не позволяет копипастить команды без использования того же replay + нужно переучиваться.

Вердикт: стоит попробовать.

Полезные ресурсы

Дополнительные плагины и информация: https://github.com/jorgebucaran/awsm.fish

Полезные статьи fish:

★★★

Проверено: dataman ()
Последнее исправление: rtxtxtrx (всего исправлений: 29)
# Определим переменные XDG
set -q XDG_DATA_HOME || set -U XDG_DATA_HOME $HOME/.local/share
set -q XDG_STATE_HOME || set -U XDG_STATE_HOME $HOME/.local/state
set -q XDG_CONFIG_HOME || set -U XDG_CONFIG_HOME $HOME/.config
set -q XDG_CACHE_HOME || set -U XDG_CACHE_HOME $HOME/.cache

Объясни кстати, если не сложно, пожалуйста, простым языком смысл вот этих вот XDG_ переменных. Все их советуют использовать, но я не вдупляю зачем.

ivan007007
()
Ответ на: комментарий от Lrrr

статья написана мной. напиши свою нейронкой я хоть поржу с нее.

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от ivan007007

переменная установлена (ложь/истина) || (или срабатывает, если ложь, те не установлена) устанавливаем переменную

rtxtxtrx ★★★
() автор топика

И в чём практический смысл вот этого?

if not status is-interactive
  exit
end

Я тебя правильно понял, что ты подразумеваешь, что ты не предполагаешь использование fish в качестве login шелла, то есть он запускается из какого-то другого, в качестве sub-шелла. И если так случилось, что обращение к нему произвелось не-интерактивно, то должен быть произведен выход обратно в родительский шелл?

ivan007007
()
Ответ на: комментарий от rtxtxtrx

Это я всё понимаю. Но вопрос был не «что это такое?», а «зачем?»

ivan007007
()

Хорошая статься, спасибо!

nuxster ★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.