使用一个命令将终端、vim 和 tmux 中的配色方案从深色切换为浅色

使用一个命令将终端、vim 和 tmux 中的配色方案从深色切换为浅色

我在用着zsh、tmux 和 vim我想知道如何仅使用一个命令在终端、vim、vim-airline 和 tmux 状态行中切换 solarized dark/light。

答案1

我已经找到了一种方法,只需在 Vim 中使用单个命令即可同时在 iTerm2、tmux 和 Vim 中切换 Solarized 的明暗:

  1. 在 iTerm2 的首选项中设置两个配置文件,一个使用 Solarized Dark 配色方案,另一个使用 Solarized Light 配色方案。颜色预设在这里非常有用,因为它们包括两个版本的 Solarized。

    iterm 太阳能型材

  2. 为每个配置文件添加一个键盘快捷键以切换到另一个配置文件(暗色切换到亮色,亮色切换到暗色)。我对两个配置文件使用了相同的快捷键,因此只需在它们之间切换即可。如果您愿意,可以使用不同的快捷键,只需对后面的步骤进行小幅修改即可。

    iterm 键盘快捷键

    如果你不熟悉这些字形,那就是Control- Option- Shift- s。你可以随意选择其他字形,但要记住它,我们稍后会需要它。我在这里只展示了 Solarized Dark,但不要忘记将其设置为两个都個人資料。

  3. 获取一些 tmux 配色方案。我使用了这个存储库在 Github 上。我将在您的计算机上将其位置称为~/tmux-colors-solarized

  4. 安装Vim 的 Solarized通过您喜欢的方法。由于我们已将 16 种 ANSI 颜色设置为 iTerm2 配置文件中的 Solarized 值,因此我们可以使用标准的 Solarized 配色方案,而不是降级的 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()
    

    最后,我们关闭该函数并定义一个commandcalled SolarSwap,它调用我们刚刚创建的函数。!默默地替换任何现有的同名命令。

    现在,在 Vim 中,只需运行:SolarSwap,Vim、tmux 和 iTerm2 就应该可以在 Solarized Light 和 Dark 之间切换。当然,您可以添加映射,.vimrc使切换更加容易。


1 iTerm2 确实有合适的 AppleScript API但它本身并没有直接改变当前选项卡配置文件的方法。只是创建新的具有指定配置文件的选项卡、窗口或拆分,或获取当前会话配置文件的(只读)名称。因此,设置键盘快捷键并使用它们切换配置文件的迂回路径。

答案2

我自己也在努力解决这个问题。我找到了一个不完美、不成熟的半解决方案,但从我所掌握的信息来看,调整终端颜色并不是一个简单的问题。

我发现 tmux 和 vim 都借用了终端配色方案中定义的 16 个 ANSI 颜色值(黑色、红色、绿色、黄色、蓝色、洋红色、青色、白色以及它们的所有“明亮”变体)。如果在你的终端配色方案,你反转 ANSI 黑白的定义IE,如果您将 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 代表“ON/Light”,od 代表“OFF/Dark”:

# 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 函数选择颜色方案(请注意,这必须在 ~/.vimrc 中的 SetColorScheme 函数之后):

call SetColorScheme()

我们可以就此停止,但是如果我们有一个正在运行的 Vim 实例,并且在 Tmux 窗格中使用我们的一个别名更改方案,Vim 不会自动重新运行 SetColorScheme 函数。

在 tmux 中切换,vim 已经打开

每当 Vim 重新聚焦时,我们可以使用自动命令来检查和重置颜色方案。不幸的是,这在终端中对 Vim 不起作用,但幸运的是,有一个插件可以帮我们解决这个问题:

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

此插件需要你的 ~/.tmux.conf 中添加以下行(或者你已经安装了tmux-敏感插入):

set -g focus-events on

使用上述选项之一(我的 ~/.tmux.conf 中只有这一行),我们可以在 ~/.vimrc 中使用 FocusGained 事件:

autocmd FocusGained * :call SetColorScheme()

这意味着一旦你从 Tmux 窗格返回 vim,Vim 的配色方案就会自动更新:

轻量示例

强制 Vim 不断检查 Tmux THEME 变量可能很容易,但我只在晚上从亮切换到暗(即每天一次),所以我不想让 Vim 在后台为这种罕见的事件进行一百万次检查:

最后要说的是,我选择将命令提示符的颜色更改为在两种配色方案下都可见。在我的 ~/.bashrc 中,我输入了 35m 来指定粗体紫色。这些数字如何指定颜色对我来说是个谜,所以我只是在 Google 上搜索了一下:

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你可以使用新的“信号”自动命令: 。然后只需从 shell 脚本autocmd Main Signal * call Solar_swap()发送 neovim 实例即可触发自动命令。有关我在 Linux 中的使用,请参阅SIGUSR1我的答案在这里

相关内容