使用一個命令將終端、vim 和 tmux 中的顏色方案從深色切換為淺色

使用一個命令將終端、vim 和 tmux 中的顏色方案從深色切換為淺色

我在用著zsh、tmux 和 vim我想知道如何僅用一個命令在終端、vim、vim-airline 和 tmux 狀態行中的日光暗/亮之間切換。

答案1

我找到了一種方法,可以在 iTerm2、tmux 和 Vim 中同時在亮色和暗色之間切換 Solarized,只需使用 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 的 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 (ie :) 指令。使我們不必每次silent都按。運行外部(Vim)命令,在本例中為.將擴展的轉義路徑連接到命令字串的其餘部分。return!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 確實有一個合適的 AppleScript API但是,我無法找到任何直接更改當前選項卡設定檔的方法。只是創造的方法新的具有指定設定檔的標籤、視窗或拆分,或取得目前會話設定檔的(唯讀)名稱。因此,設定鍵盤快速鍵並使用它們來切換設定檔的迂迴路徑。

答案2

我自己也在為這個問題而苦苦掙扎。我找到了一個不完美的、古怪的半解決方案,但從我收集到的情況來看,馴服終端顏色並不是一個小問題。

我發現 tmux 和 vim 都藉用了終端配色方案中定義的 16 種 ANSI 顏色值(黑色、紅色、綠色、黃色、藍色、洋紅色、青色、白色及其所有「明亮」變體)。如果在你的終端配色方案,你反轉 ANSI 黑白的定義IE,將黑色/亮黑色設定為淺色背景顏色,將白色/亮白色設定為深色前景色),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 重新聚焦時,我們可以使用 autocmd 來檢查和重設顏色方案。不幸的是,這對於終端中的 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 以粗體字體指定紫色。這些數字如何指定顏色對我來說很神秘,所以我只是用谷歌搜尋了一下:

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()。然後只需從 shell 腳本發送 neovim 實例SIGUSR1即可觸發 autocmd。關於我在linux中的使用,請參閱我的回答在這裡

相關內容