vim - Vim 如何猜测 xterm 上的背景颜色?

标签 vim tmux xterm

Vim 能够正确猜测 Xterm 的背景颜色以设置其内部选项 bgdarkwhite根据终端的一个。 Vim 能够正确地做到这一点 只有TERM设置为 xterm {, -color , -256color } 或 linux但没有其他人喜欢 tmuxscreen .

Vim 怎么猜的?

我发现大多数人都强制设置 background选项 darklight在他们的 .vimrc文件;但我想要一种方法来猜测与 Vim 相同的方式,独立于终端是 xterm , tmux , screen .

最佳答案

默认设置在 Vim 源代码(用 C 编程语言编写)中定义(硬编码)。自 6.1.136 版以来,有一个修复程序可以在带有“linux”TERM 的 Vim 的 GUI 变体中不使用“dark”,它可以帮助我找到实际代码:

http://ftp.twaren.net/vim/patches/6.1.136

Patch 6.1.136
Problem:    When $TERM is "linux" the default for 'background' is "dark", even
        though the GUI uses a light background. (Hugh Allen)
Solution:   Don't mark the option as set when defaulting to "dark" for the
        linux console.  Also reset 'background' to "light" when the GUI
        has a light background.
Files:      src/option.c

逻辑在这里,默认值:https://fossies.org/dox/vim-7.4/option_8c_source.html#l00566

  563     {"background",  "bg",   P_STRING|P_VI_DEF|P_RCLR,
  564                 (char_u *)&p_bg, PV_NONE,
  565                 {
  566 #if (defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI)
  567                 (char_u *)"dark",
  568 #else
  569                 (char_u *)"light",
  570 #endif

检测终端背景:https://fossies.org/dox/vim-7.4/option_8c_source.html#l03754

 3725     /* For DOS console the default is always black. */
 3726 #if !((defined(MSDOS) || defined(OS2) || defined(WIN3264)) && !defined(FEAT_GUI))
 3727     /*
 3728      * If 'background' wasn't set by the user, try guessing the value,
 3729      * depending on the terminal name.  Only need to check for terminals
 3730      * with a dark background, that can handle color.
 3731      */
 3732     idx = findoption((char_u *)"bg");
 3733     if (idx >= 0 && !(options[idx].flags & P_WAS_SET)
 3734                          && *term_bg_default() == 'd')
 3735     {
 3736     set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0);
 3737     /* don't mark it as set, when starting the GUI it may be
 3738      * changed again */
 3739     options[idx].flags &= ~P_WAS_SET;
 3740     }
 3741 #endif
 3754 /*
 3755  * Return "dark" or "light" depending on the kind of terminal.
 3756  * This is just guessing!  Recognized are:
 3757  * "linux"      Linux console
 3758  * "screen.linux"   Linux console with screen
 3759  * "cygwin"     Cygwin shell
 3760  * "putty"      Putty program
 3761  * We also check the COLORFGBG environment variable, which is set by
 3762  * rxvt and derivatives. This variable contains either two or three
 3763  * values separated by semicolons; we want the last value in either
 3764  * case. If this value is 0-6 or 8, our background is dark.
 3765  */
 3766     static char_u *
 3767 term_bg_default()
 3768 {
 3769 #if defined(MSDOS) || defined(OS2) || defined(WIN3264)
 3770     /* DOS console nearly always black */
 3771     return (char_u *)"dark";
 3772 #else
 3773     char_u  *p;
 3774
 3775     if (STRCMP(T_NAME, "linux") == 0
 3776         || STRCMP(T_NAME, "screen.linux") == 0
 3777         || STRCMP(T_NAME, "cygwin") == 0
 3778         || STRCMP(T_NAME, "putty") == 0
 3779         || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
 3780         && (p = vim_strrchr(p, ';')) != NULL
 3781         && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
 3782         && p[2] == NUL))
 3783     return (char_u *)"dark";
 3784     return (char_u *)"light";
 3785 #endif
 3786 }

图形界面修复:

 4044 gui_bg_default()
 4045 {
 4046     if (gui_get_lightness(gui.back_pixel) < 127)
 4047     return (char_u *)"dark";
 4048     return (char_u *)"light";
 4049 }

更新:
对于 vim-7.4.1689 (debian/ubuntu),我使用调试信息重建了 Vim 包(-O2 -g 默认选项;在剥离并打包到 deb 之前)并运行 TERM=xterm gdb --args vim-7.4.1689/src/vim-basic/vim -ewatch p_bg . p_bg的第一次变更来自 term_bg_default()light ,第二个来自... main :may_req_termresponse() (如果定义了 FEAT_TERMRESPONSE)-> vpeekc_nomap -> vpeekc -> vgetorpeek -> check_termcode -> set_option_value("bg",..) -> set_string_option .

https://github.com/vim/vim/blob/54c10ccf9274880e83093a99690e7bfa9a2d2fa8/src/term.c

第 3302 行 - may_req_bg_color()颜色,来自 main.c紧随其后 starttermcap()/日志消息“启动 termcap”;我添加了请求的预处理定义:

/*
 * Similar to requesting the version string: Request the terminal background
 * color when it is the right moment.
 */
    void
may_req_bg_color(void)
...

    {(int)KS_RBG,   "\033]11;?\007",

    {(int)KS_RBG,   "[RBG]"},

第 4286 行 - 处理来自 termcap 请求的响应:

check_termcode( ....

    /* Check for background color response from the terminal:
     *
     *       {lead}11;rgb:{rrrr}/{gggg}/{bbbb}{tail}
     *
     * {lead} can be <Esc>] or OSC
     * {tail} can be '\007', <Esc>\ or STERM.
     *
     * Consume any code that starts with "{lead}11;", it's also
     * possible that "rgba" is following.
     */

        if (i - j >= 21 && STRNCMP(tp + j + 3, "rgb:", 4) == 0
            && tp[j + 11] == '/' && tp[j + 16] == '/'
            && !option_was_set((char_u *)"bg"))
        {/* TODO: don't set option when already the right value */
            LOG_TR("Received RBG");
            rbg_status = RBG_GOT;
            set_option_value((char_u *)"bg", 0L, (char_u *)(
                (3 * '6' < tp[j+7] + tp[j+12] + tp[j+17])
                ? "light" : "dark"), 0);
            reset_option_was_set((char_u *)"bg");

由 7.4.757 补丁添加 http://ftp.vim.org/vim/patches/7.4/7.4.757
Patch 7.4.757
Problem:    Cannot detect the background color of a terminal.
Solution:   Add T_RBG to request the background color if possible. (Lubomir
            Rintel)
Files:      src/main.c, src/term.c, src/term.h, src/proto/term.pro

#define T_RBG   (term_str(KS_RBG))  /* request background RGB */

您的 tmux/screen 可能无法实现“[RBG]”请求;通过在 xterm 和 tmux 中运行来检查并比较输出:
echo -e '\033]11;?\007'

您可以定义 COLORFGBG(并且在 Neovim 中有关于它的错误: https://github.com/neovim/neovim/issues/2764 )
gnome-terminal 有错误报告可以设置它
https://bugzilla.gnome.org/show_bug.cgi?id=733423

Various terminals, including urxvt and konsole, set an environment variable "COLORFGBG" to allow applications to detect the foreground and background colors. Various programs, such as Vim, use this to determine whether to use a color scheme that works best on a light or dark background. Please consider setting this variable in gnome-terminal as well.



Egmont 在 bug https://bugzilla.gnome.org/show_bug.cgi?id=733423 中有一些选项设置 COLORFGBG.bashrc .

您可以在您的“vimrc”( ~/.vimrc )中更改此设置,或者通过更改 /usr/share/vim/vimrc 在您的操作系统上全局更改此设置。或通过重新编译自定义版本在 vim 源中或通过向 Vim 作者报告错误/向他们发送补丁在 Vim 源中。

documentation of "bg"描述部分逻辑并给出vimrc的解决方案:

When setting 'background' to the default value with:

  :set background&

Vim will guess the value. In the GUI this should work correctly, in other cases Vim might not be able to guess the right value.

When starting the GUI, the default value for 'background' will be "light". When the value is not set in the .gvimrc, and Vim detects that the background is actually quite dark, 'background' is set to "dark". ....

Normally this option would be set in the .vimrc file. Possibly depending on the terminal name. Example:

      :if &term == "pcterm"
        :  set background=dark
        :endif

When this option is set, the default settings for the highlight groups will change. To use other settings, place ":highlight" commands AFTER the setting of the 'background' option.

关于vim - Vim 如何猜测 xterm 上的背景颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38287889/

相关文章:

windows - 在 Windows 资源管理器中隐藏 Vim 备份 (*~)

tmux - Tmux边框用虚线绘制;如何将它们更改为连续线?

tmux - 将当前 tmux session 转换为配置文件

macos - 如何为 X11 应用程序(例如 xmgrace)设置默认启动窗口大小

vim - 在 (n) 个字符后插入一个字符并重复 (n) 次 - vim

bash - 从 shell 脚本执行 Vim 命令

conda - 在 conda 中,tmux 和 emacs 抛出 "error while loading shared libraries: libtinfo.so.6"

node.js - 交叉配送终端开通

ssh - SSH -X 和 ssh -Y 的区别

vim - 命令行参数中.vimrc的选项?