]> granicus.if.org Git - vim/commitdiff
patch 7.4.770 v7.4.770
authorBram Moolenaar <Bram@vim.org>
Fri, 10 Jul 2015 12:05:10 +0000 (14:05 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 10 Jul 2015 12:05:10 +0000 (14:05 +0200)
Problem:    Background color response with transparency is not ignored.
Solution:   Change the way escape sequences are recognized. (partly by
            Hirohito Higashi)

src/ascii.h
src/term.c
src/version.c

index a3cfecff717b2361f4314ff771d7e0f610cb9aaf..7ed736a9f6fecdf66239f384dd055437862d16e0 100644 (file)
 #define ESC_STR_nc     "\033"
 #define DEL            0x7f
 #define DEL_STR                (char_u *)"\177"
-#define CSI            0x9b    /* Control Sequence Introducer */
-#define CSI_STR                "\233"
-#define DCS            0x90    /* Device Control String */
-#define STERM          0x9c    /* String Terminator */
 
 #define POUND          0xA3
 
 #define ESC_STR_nc     "\x27"
 #define DEL            0x07
 #define DEL_STR                (char_u *)"\007"
-/* TODO: EBCDIC Code page dependent (here 1047) */
-#define CSI            0x9b    /* Control Sequence Introducer */
-#define CSI_STR                "\233"
-#define DCS            0x90    /* Device Control String */
-#define STERM          0x9c    /* String Terminator */
 
 #define POUND          0xB1
 
@@ -173,6 +164,13 @@ extern char MetaCharTable[];
 
 #endif /* defined EBCDIC */
 
+/* TODO: EBCDIC Code page dependent (here 1047) */
+#define CSI            0x9b    /* Control Sequence Introducer */
+#define CSI_STR                "\233"
+#define DCS            0x90    /* Device Control String */
+#define OSC            0x9d    /* Operating System Command */
+#define STERM          0x9c    /* String Terminator */
+
 /*
  * Character that separates dir names in a path.
  * For MS-DOS, WIN32 and OS/2 we use a backslash.  A slash mostly works
index 8d8ac407f76e9b9464becd498550a3be7ce248a1..d35a57e0464f563bd6fd4093b7bc6949e196d1c7 100644 (file)
@@ -2364,7 +2364,7 @@ term_7to8bit(p)
        if (p[1] == '[')
            return CSI;
        if (p[1] == ']')
-           return 0x9d;
+           return OSC;
        if (p[1] == 'O')
            return 0x8f;
     }
@@ -4261,18 +4261,11 @@ check_termcode(max_offset, buf, bufsize, buflen)
             * - Cursor position report: <Esc>[{row};{col}R
             *   The final byte must be 'R'. It is used for checking the
             *   ambiguous-width character state.
-            *
-            * - Background color response:
-            *       <Esc>]11;rgb:{rrrr}/{gggg}/{bbbb}\007
-            *   Or
-            *       <Esc>]11;rgb:{rrrr}/{gggg}/{bbbb}ST
-            *   The final byte must be '\007' or ST(0x9c or ESC\).
             */
-           char_u *argp = tp[0] == CSI ? tp + 1 : tp + 2;
+           char_u *argp = tp[0] == ESC ? tp + 2 : tp + 1;
 
-           if ((*T_CRV != NUL || *T_U7 != NUL || *T_RBG != NUL)
-                       && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
-                           || (tp[0] == ESC && tp[1] == ']' && len >= 24)
+           if ((*T_CRV != NUL || *T_U7 != NUL)
+                       && ((tp[0] == ESC && len >= 3 && tp[1] == '[')
                            || (tp[0] == CSI && len >= 2))
                        && (VIM_ISDIGIT(*argp) || *argp == '>' || *argp == '?'))
            {
@@ -4410,44 +4403,80 @@ check_termcode(max_offset, buf, bufsize, buflen)
                    key_name[1] = (int)KE_IGNORE;
                    slen = i + 1;
                }
-               else if (*T_RBG != NUL
-                       && len >= 24 - (tp[0] == CSI)
-                       && len >= 24 - (tp[0] == CSI) + (argp[21] == ESC)
-                       && argp[0] == '1' && argp[1] == '1'
-                       && argp[2] == ';' && argp[3] == 'r' && argp[4] == 'g'
-                       && argp[5] == 'b' && argp[6] == ':'
-                       && argp[11] == '/' && argp[16] == '/'
-                       && (argp[21] == '\007' || argp[21] == STERM
-                           || (argp[21] == ESC && argp[22] == '\\')))
-               {
-                   LOG_TR("Received RBG");
-                   rbg_status = RBG_GOT;
-                   if (!option_was_set((char_u *)"bg"))
+           }
+
+           /* 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.
+            */
+           else if (*T_RBG != NUL
+                       && ((tp[0] == ESC && len >= 2 && tp[1] == ']')
+                           || tp[0] == OSC))
+           {
+               j = 1 + (tp[0] == ESC);
+               if (len >= j + 3 && (argp[0] != '1'
+                                        || argp[1] != '1' || argp[2] != ';'))
+                 i = 0; /* no match */
+               else
+                 for (i = j; i < len; ++i)
+                   if (tp[i] == '\007' || (tp[0] == OSC ? tp[i] == STERM
+                       : (tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')))
                    {
-                       set_option_value((char_u *)"bg", 0L, (char_u *)(
-                                   (3 * '6' < argp[7] + argp[12] + argp[17])
-                                                     ? "light" : "dark"), 0);
-                       reset_option_was_set((char_u *)"bg");
-                       redraw_asap(CLEAR);
+                       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");
+                           redraw_asap(CLEAR);
+                       }
+
+                       /* got finished code: consume it */
+                       key_name[0] = (int)KS_EXTRA;
+                       key_name[1] = (int)KE_IGNORE;
+                       slen = i + 1 + (tp[i] == ESC);
+                       break;
                    }
-                   key_name[0] = (int)KS_EXTRA;
-                   key_name[1] = (int)KE_IGNORE;
-                   slen = 24 - (tp[0] == CSI) + (argp[21] == ESC);
+               if (i == len)
+               {
+                   LOG_TR("not enough characters for RB");
+                   return -1;
                }
            }
 
-           /* Check for '<Esc>P1+r<hex bytes><Esc>\'.  A "0" instead of the
-            * "1" means an invalid request. */
+           /* Check for key code response from xterm:
+            *
+            * {lead}{flag}+r<hex bytes><{tail}
+            *
+            * {lead} can be <Esc>P or DCS
+            * {flag} can be '0' or '1'
+            * {tail} can be Esc>\ or STERM
+            *
+            * Consume any code that starts with "{lead}.+r".
+            */
            else if (check_for_codes
-                   && ((tp[0] == ESC && tp[1] == 'P' && len >= 2)
+                   && ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
                        || tp[0] == DCS))
            {
-               j = 1 + (tp[0] != DCS);
-               for (i = j; i < len; ++i)
-                   if ((tp[i] == ESC && tp[i + 1] == '\\' && i + 1 < len)
+               j = 1 + (tp[0] == ESC);
+               if (len >= j + 3 && (argp[1] != '+' || argp[2] != 'r'))
+                 i = 0; /* no match */
+               else
+                 for (i = j; i < len; ++i)
+                   if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
                            || tp[i] == STERM)
                    {
-                       if (i - j >= 3 && tp[j + 1] == '+' && tp[j + 2] == 'r')
+                       if (i - j >= 3)
                            got_code_from_term(tp + j, i);
                        key_name[0] = (int)KS_EXTRA;
                        key_name[1] = (int)KE_IGNORE;
@@ -4457,8 +4486,10 @@ check_termcode(max_offset, buf, bufsize, buflen)
 
                if (i == len)
                {
+                   /* These codes arrive many together, each code can be
+                    * truncated at any point. */
                    LOG_TR("not enough characters for XT");
-                   return -1;          /* not enough characters */
+                   return -1;
                }
            }
        }
index cd2604875e0f265d2478658437f69ea51ca45a34..3e0984585620e0d0acdbeeee382be0c0a963569f 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    770,
 /**/
     769,
 /**/