Переключение цветовой схемы в терминале, vim и tmux с темной на светлую с помощью одной команды

Переключение цветовой схемы в терминале, vim и tmux с темной на светлую с помощью одной команды

я используюzsh, tmux и vimи я хотел бы узнать, как переключаться между темным/светлым солярием в терминале, vim, vim-airline и строке состояния tmux с помощью всего одной команды.

решение1

Я придумал способ одновременного переключения Solarized между светлым и темным режимами для iTerm2, tmux и Vim с помощью одной команды из Vim:

  1. Настройте два профиля в настройках iTerm2, один с цветовой схемой Solarized Dark, а другой с цветовой схемой Solarized Light. Цветовые пресеты здесь очень полезны, поскольку они включают обе версии Solarized.

    соляризованные профили iterm

  2. Добавьте сочетание клавиш для каждого профиля, чтобы переключаться между ними (темный переключает на светлый, светлый переключает на темный). Я использовал одно и то же сочетание клавиш для обоих профилей, поэтому оно просто переключается между ними. Вы можете использовать другие сочетания клавиш, если хотите, вам просто нужно будет внести небольшое изменение в более поздний шаг.

    сочетание клавиш iterm

    Если вы не знакомы с глифами, то это Control- Option- Shift- s. Можете смело выбирать что-то другое, но помните, нам это понадобится позже. И я показываю здесь только Solarized Dark, но не забудьте настроить его дляобапрофили.

  3. Получите себе несколько цветовых схем tmux. Я использовал те, что изэтот репозиторийна Github. Я буду обозначать его местоположение на вашем компьютере как ~/tmux-colors-solarized.

  4. УстановитьСоляризовано для Vimс помощью предпочитаемого вами метода. Поскольку мы установили 16 цветов ANSI для значений Solarized в профилях iTerm2, мы можем использоватьстандартная соляризованная цветовая схема, а не ухудшенная версия из 256 цветов.

  5. Добавьте в свой файл функцию .vimrcи, при желании, команду:

    function! Solar_swap()
        if &background ==? 'dark'
            set background=light
            execute "silent !tmux source-file " . shellescape(expand('~/tmux-colors-solarized/tmuxcolors-light.conf'))
        else
            set background=dark
            execute "silent !tmux source-file " . shellescape(expand('~/tmux-colors-solarized/tmuxcolors-dark.conf'))
        endif
        silent !osascript -e 'tell app "System Events" to keystroke "s" using {shift down, option down, control down}'
    endfunction
    
    command! SolarSwap call Solar_swap()
    

    Построчное...объяснение:

    function! Solar_swap()
    

    Определите functionименованную функцию Solar_swap, которая не принимает параметров (). !В конце functionзаставляет ее молча заменить существующую функцию с тем же именем, что удобно, если вы в конечном итоге .vimrcснова используете свой источник.

        if &background ==? 'dark'
    

    Простая проверка, является ли фон Vim в данный момент темным. ==?выполняет сравнение без учета регистра. &Необходимо использовать настройку (например, background) в выражении.

            set background=light
    

    Просто устанавливаю светлый фон Vim.

            execute "silent !tmux source-file " . shellescape(expand('~/tmux-colors-solarized/tmuxcolors-light.conf'))
    

    executeследующая строка как :команда Ex (т.е. ). silentизбавляет нас от необходимости нажимать returnкаждый раз. !запускает внешнюю (для Vim) команду, в данном случае tmux source-file [path]. Она .объединяет расширенный, экранированный путь с остальной частью командной строки.

        else
            set background=dark
            execute "silent !tmux source-file " . shellescape(expand('~/tmux-colors-solarized/tmuxcolors-dark.conf'))
        endif
    

    Этот фрагмент по сути представляет собой просто версию вышеприведенных строк, выполненную от светлого к темному.

        silent !osascript -e 'tell app "System Events" to keystroke "s" using {shift down, option down, control down}'
    

    silent !то же самое, что и раньше. osascriptзапустит для нас некоторый AppleScript. -eозначает выполнить следующий аргумент как одну строку скрипта. Строка, которую мы запускаем, — это та, которая отправляет это сочетание клавиш из шага 2 в активное приложение, которое, с точки зрения операционной системы, должно быть iTerm2. 1 Вам может потребоваться изменить строку, чтобы она соответствовала вашему выбору сочетания клавиш. Обратите внимание, что если у вас было два разных сочетания клавиш для переключения iTerm2, вам нужно будет переместить эту строку вверх в ifветви и изменить нажатия клавиш для соответствия.

    endfunction
    
    command! SolarSwap call Solar_swap()
    

    И наконец, мы закрываем функцию и определяем commandвызываемую функцию SolarSwap, которая вызывает только что созданную нами функцию. !Она молча заменяет любую существующую команду с тем же именем.

    Теперь, из Vim, просто запустите :SolarSwapи Vim, tmux и iTerm2 должны переключаться между Solarized Light и Dark. Вы, конечно, можете добавить сопоставление к своему, .vimrcчтобы сделать переключение еще проще.


1 iTerm2 имеет надлежащий API AppleScriptОднако, я не смог найти никаких средств для прямого изменения профиля текущей вкладки. Просто способы созданияновыйвкладки, окна или разделения с указанным профилем или получить (только для чтения) имя профиля текущего сеанса. Таким образом, окольный путь настройки сочетаний клавиш и их использования для переключения профилей.

решение2

Я сам борюсь с этой проблемой. Я остановился на несовершенном, хакерском полурешении, но из того, что я понял, укрощение терминальных цветов — не совсем тривиальная задача.

Я обнаружил, что и tmux, и vim заимствуют 16 значений цветов ANSI, определенных в цветовой схеме вашего терминала (черный, красный, зеленый, желтый, синий, пурпурный, голубой, белый и все их «яркие» варианты). Если в вашемсветцветовая схема терминала, выинвертировать определения ANSI черного и белого(то есть,установите black/brightblack в качестве светлого цвета фона и white/brightwhite в качестве темного цвета переднего плана), tmux и vim последуют этому примеру. Пока вы используете только светлые/темные варианты одной цветовой схемы, это должно работать прилично.

введите описание изображения здесь

Как вы можете видеть на этом снимке экрана, он не идеален (спереди — терминал, сзади — MacVim — обратите внимание на разницу в тексте авиакомпании, а также на неразборчивый черный блок около середины, который должен быть светлым текстом на темном фоне), но он справляется на 99% без необходимости изменять какие-либо настройки vim/tmux/vim-airline.

введите описание изображения здесь

решение3

Я реализовал способ переключения между светлой и темной цветовой схемой для Vim и Tmux за один раз с помощью простого сочетания клавиш (вводимого либо в Vim, либо в Tmux). Я использую Bash, а не Zsh, но надеюсь, это кому-то поможет. У меня нет репутации, чтобы показывать изображения, но она у меня естьвсе в блоге здесь.

В моем случае я могу сделать либо:

Из панели Tmux: 1a) Псевдоним «ol» переключает Vim и Tmux в светлый режим. 1b) Псевдоним «od» переключает Vim и Tmux в темный режим.

Из Vim: 2) «Leader-o» переключает Vim и Tmux между светлой и темной цветовыми схемами. темный пример легкий пример

Это работает так: я определяю переменную окружения Tmux, которая отслеживает, есть ли у нас светлая или темная цветовая схема. Всякий раз, когда я переключаюсь, будь то из Vim или панели Tmux, переменная будет обновляться. Существующие и новые панели Tmux, а также существующие и новые экземпляры Vim будут проверять эту переменную и следовать схеме.

Реализация кода

Шаг 1: Переключение с панели Tmux

Во-первых, я настроил свой ~/.bashrc так, чтобы он автоматически запускал Tmux и пытался подключиться к сеансу под названием 'main' или создать его, если он не существует. Я считаю, что это работает для меня, но вы можете изменить этот шаг.

После запуска Tmux я запрашиваю переменную окружения под названием 'THEME', если она не равна 'THEME=light' (или просто не существует), то мы переходим на темную тему. Это означает, что при первом запуске сеанса Tmux мы по умолчанию будем использовать темную тему:

if command -v tmux>/dev/null; then
    [[ ! $TERM =~ screen ]] && [ -z $TMUX ] && tmux new-session -A -s main

    # check if we have been switched to light, else go dark
    [[ ! $(tmux show-environment | grep THEME) =~ 'THEME=light' ]] && 
    tmux set-environment THEME dark
fi

В начале моего файла ~/tmux.conf я начинаю с поиска вторичного файла Tmux, который содержит выбранные мной темные цвета. Эти значения могут быть позже переопределены светлой схемой:

# source colorscheme
set -g default-terminal 'screen-256color'
source-file ~/.tmux_dark.conf

Вот цвета темной темы, которые у меня есть:

# dark colours
# fg = thin line
set -g pane-border-style "bg=colour234 fg=colour244"
set -g pane-active-border-style "bg=colour234 fg=colour208"
# fg = text
set -g window-style 'fg=colour248,bg=colour234'
set -g window-active-style 'fg=colour252,bg=colour235'
# Customize the status line
set -g status-fg colour208
set -g status-bg colour234

Помимо ~/.tmux_dark.conf у меня есть ~/.tmux_light.conf:

# light colours
# fg = thin line
set -g pane-border-style "bg=colour253 fg=colour244"
set -g pane-active-border-style "bg=colour253 fg=colour208"
# fg = text
set -g window-style 'fg=colour238,bg=colour253'
set -g window-active-style 'fg=colour238,bg=colour231'
# Customize the status line
set -g status-fg colour208
set -g status-bg colour253

Если я нахожусь в панели Tmux и хочу переключить цветовые схемы, я просто беру соответствующий файл и обновляю переменную THEME. У меня есть два псевдонима в моем ~/.bashrc для этого. Я помню их как ol для «ВКЛ/Светло» и od для «ВЫКЛ/Темно»:

# switch between light and dark themes
alias ol="tmux source-file ~/.tmux_light.conf; tmux set-environment THEME 'light'"
alias od="tmux source-file ~/.tmux_dark.conf; tmux set-environment THEME 'dark'"

Шаг 2: Переход с Vim

В моем ~/.vimrc я определил две функции: одну для установки цветовой схемы и другую для обработки чтения и обновления переменной Tmux THEME. Цветовая схема, которую мы выбираем, диктуется переменной Tmux THEME, которую мы считываем с помощью системного вызова Tmux. Это возвращает переменную THEME, а также сообщение «Нажмите ENTER или введите команду для продолжения». Очевидно, что нас интересует только переменная. Если переменная указывает, что мы должны быть темными, мы выбираем темную цветовую схему (в моем случае zenburn), в противном случае мы выбираем светлую (в моем случае seoul256-light). Важно, что поскольку я проверяю совпадение с «THEME=dark», мы должны взять только первые 10 символов сообщения, возвращаемого системным вызовом:

function! SetColorScheme()
    " check if tmux colorsheme is light or dark, and pick for vim accordingly
    if system('tmux show-environment THEME')[0:9] == 'THEME=dark'
        colorscheme zenburn
    else
        colorscheme seoul256-light
    endif
endfunction

Переключение цветовой схемы между светлой и темной осуществляется вызовом другой функции. Функция также повторно использует соответствующую цветовую схему Tmux и обновляет переменную THEME. После обновления переменной THEME мы вызываем функцию SetColorScheme выше, чтобы изменить цвета Vim:

function! Toggle_Light_Dark_Colorscheme()
    if system('tmux show-environment THEME')[0:9] == 'THEME=dark'
        :silent :!tmux source-file ~/.tmux_light.conf
        :silent :!tmux set-environment THEME 'light'
    else
        :silent :!tmux source-file ~/.tmux_dark.conf
        :silent :!tmux set-environment THEME 'dark'
    endif
    :call SetColorScheme()
endfunction

Мы можем создать сопоставление (или команду) для быстрого переключения цветовой схемы следующим образом:

nnoremap <Leader>o :call Toggle_Light_Dark_Colorscheme()<cr>

Когда мы открываем новый экземпляр Vim, переменная Tmux THEME уже будет отправлена, поэтому мы выбираем цветовую схему с помощью функции SetColorScheme (обратите внимание, что она должна располагаться после функции SetColorScheme в вашем ~/.vimrc):

call SetColorScheme()

На этом можно было бы остановиться, но в случае, если у нас запущен экземпляр Vim и мы изменим схему с помощью одного из наших псевдонимов из панели Tmux, Vim не будет автоматически перезапускать функцию SetColorScheme.

переключить в tmux, vim уже открыт

Мы можем использовать autocmd для проверки и сброса цветовой схемы всякий раз, когда Vim переключается на другую фокусировку. К сожалению, это не работает для Vim в терминале, но, к счастью, есть плагин, который решает эту проблему для нас:

Plugin 'tmux-plugins/vim-tmux-focus-events'

Для этого плагина требуется следующая строка в вашем ~/.tmux.conf (или чтобы вы установилиtmux-чувствительныйплагин):

set -g focus-events on

С помощью одного из приведенных выше вариантов (у меня просто есть строка в моем ~/.tmux.conf) мы можем использовать событие FocusGained в ~/.vimrc:

autocmd FocusGained * :call SetColorScheme()

Это будет означать, что как только вы вернетесь в vim из панели Tmux, цветовая схема Vim обновится автоматически:

легкий пример

Вероятно, было бы легко заставить Vim постоянно проверять переменную Tmux THEME, но я переключаюсь со светлого на темный режим только вечером (т. е. один раз в день), поэтому я не хочу заставлять Vim выполнять миллион проверок в фоновом режиме для такого редкого события:

Последнее замечание: я решил изменить цвет командной строки, чтобы она была видна в обеих цветовых схемах. В моем ~/.bashrc я указал 35m, чтобы указать фиолетовый цвет жирным шрифтом. Для меня загадка, как эти числа определяют цвет, поэтому я просто немного погуглил:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;35m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$ '

Однако выбирать цвета в файле ~/.tmux.conf легко с помощью этого кода, который можно вставить в терминал для отображения цветовой сетки в диапазоне 0-255:

for i in {0..255} ; do \
printf "\x1b[48;5;%sm%3d\e[0m " "$i" "$i"; \
if (( i == 15 )) || (( i > 15 )) && (( (i-15) % 6 == 0 )); then \
printf "\n"; \
fi; done

решение4

Если вы ищете способ изменить схему вне vim и автоматически обновить интерфейс vim, см :h t_RB. .Этот ответссылается на обновление механизма терминальных запросов в vim версии 8.0.1129, 2017.

Если вы хотите использовать neovim после этого, v0.4.0-239-g36378c33cвы можете использоватьновый автокомандный "Сигнал": autocmd Main Signal * call Solar_swap(). Затем просто отправьте экземпляры neovim SIGUSR1из вашего скрипта оболочки, чтобы запустить autocmd. Для моего использования в Linux см.мой ответ здесь.

Связанный контент