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

时间:2016-07-10 01:51:14

标签: vim tmux xterm

Vim能够正确猜测Xterm的背景颜色,以便根据终端的选项将其内部选项bg设置为darkwhite。当TERM设置为xterm {,-color-256color}或linux时,Vim才能正确执行 但没有其他人喜欢tmuxscreen

Vim如何猜测?

我发现大多数人都强制将background选项设置为dark文件中的light.vimrc;但是我想要一种方式来猜测Vim的方式,与终端xtermtmuxscreen无关。

1 个答案:

答案 0 :(得分:4)

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

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 }

GUI修复:

 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),我使用调试信息(-O2 -g默认选项;在剥离并打包到deb之前)重建了Vim包,并使用TERM=xterm gdb --args vim-7.4.1689/src/vim-basic/vim -e运行watch p_bgp_bg的第一次更改是term_bg_default()light,第二次来自...... mainmay_req_termresponse()(如果定义了FEAT_TERMRESPONSE) - &gt; vpeekc_nomap - &gt; vpeekc - &gt; vgetorpeek - &gt; check_termcode - &gt; set_option_value("bg",..) - &gt; set_string_option

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

第3302行 - may_req_bg_color()颜色,在main.c /日志消息“start termcap”之后从starttermcap()调用;我添加了预处理的请求定义:

/*
 * 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

  

各种终端(包括urxvt和konsole)设置环境变量“COLORFGBG”以允许应用程序检测前景色和背景色。各种程序,例如Vim,使用它来确定是否使用在浅色或深色背景上效果最佳的配色方案。请考虑在gnome-terminal中设置此变量。

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

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

documentation of "bg"描述了逻辑的一部分,并为vimrc提供了解决方案:

  

将“background”设置为默认值时使用:

  :set background&
     

Vim会猜测这个值。在GUI中这应该正常工作,     在其他情况下,Vim可能无法猜出正确的值。

     

启动GUI时,“background”的默认值为       "light"。如果未在.gvimrc中设置该值,则Vim会检测到该值       背景实际上很暗,“background”设置为       "dark"。 ....

     

通常,此选项将在.vimrc文件中设置。或者       取决于终端名称。例如:

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

设置此选项后,突出显示组的默认设置       将改变。要使用其他设置,请在“:highlight”命令后面       “背景”选项的设置。