]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0970: terminal properties are not available in Vim script v8.2.0970
authorBram Moolenaar <Bram@vim.org>
Sat, 13 Jun 2020 13:47:25 +0000 (15:47 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 13 Jun 2020 13:47:25 +0000 (15:47 +0200)
Problem:    Terminal properties are not available in Vim script.
Solution:   Add the terminalprops() function.

runtime/doc/eval.txt
runtime/doc/testing.txt
runtime/doc/usr_41.txt
src/evalfunc.c
src/globals.h
src/main.c
src/proto/term.pro
src/term.c
src/testdir/test_termcodes.vim
src/testing.c
src/version.c

index 78588bfd3ca8db6fc482eeca746479146764c5de..5399ac2335485806c158f8314a4c719a730d471f 100644 (file)
@@ -2194,7 +2194,8 @@ v:termresponse    The escape sequence returned by the terminal for the |t_RV|
                'c', with only digits and ';' in between.
                When this option is set, the TermResponse autocommand event is
                fired, so that you can react to the response from the
-               terminal.
+               terminal.  You can use |terminalprops()| to see what Vim
+               figured out about the terminal.
                The response from a new xterm is: "<Esc>[> Pp ; Pv ; Pc c".  Pp
                is the terminal type: 0 for vt100 and 1 for vt220.  Pv is the
                patch level (since this was introduced in patch 95, it's
@@ -2870,6 +2871,7 @@ term_setsize({buf}, {rows}, {cols})
                                none    set the size of a terminal
 term_start({cmd} [, {options}])        Number  open a terminal window and run a job
 term_wait({buf} [, {time}])    Number  wait for screen to be updated
+terminalprops()                        Dict    properties of the terminal
 test_alloc_fail({id}, {countdown}, {repeat})
                                none    make memory allocation fail
 test_autochdir()               none    enable 'autochdir' during startup
@@ -10390,6 +10392,41 @@ tempname()                                     *tempname()* *temp-file-name*
 
 term_ functions are documented here: |terminal-function-details|
 
+
+terminalprops()                                                *terminalprops()*
+               Returns a dictionary with properties of the terminal that Vim
+               detected from the response to |t_RV| request.  See
+               |v:termresponse| for the response itself.  If |v:termresponse|
+               is empty most values here will be 'u' for unknown.
+                  cursor_style         wether sending |t_RS| works  **
+                  cursor_blink_mode    wether sending |t_RC| works  **
+                  underline_rgb        whether |t_8u| works **
+                  mouse                mouse type supported
+
+               ** value 'u' for unknown, 'y' for yes, 'n' for no
+
+               If the |+termresponse| feature is missing then the result is
+               an empty dictionary.
+
+               If "cursor_style" is 'y' then |t_RS| will be send to request the
+               current cursor style.
+               If "cursor_blink_mode" is 'y' then |t_RC| will be send to
+               request the cursor blink status.
+               "cursor_style" and "cursor_blink_mode" are also set if |t_u7|
+               is not empty, Vim will detect the working of sending |t_RS|
+               and |t_RC| on startup.
+
+               When "underline_rgb" is not 'y', then |t_8u| will be made empty.
+               This avoids sending it to xterm, which would clear the colors.
+
+               For "mouse" the value 'u' is unknown
+
+               Also see:
+               - 'ambiwidth' - detected by using |t_u7|.
+               - |v:termstyleresp| and |v:termblinkresp| for the response to
+                 |t_RS| and |t_RC|.
+
+
 test_ functions are documented here: |test-functions-details|
 
 
index c708beccce20c3794ce421e149fe18f72a0ebbd8..12990d3ec501610130c9f11353115b89625fcf88 100644 (file)
@@ -165,6 +165,8 @@ test_override({name}, {val})                                *test_override()*
                                terminals
                no_wait_return  set the "no_wait_return" flag.  Not restored
                                with "ALL".
+               term_props   reset all terminal properties when the version
+                            string is detected
                ALL          clear all overrides ({val} is not used)
 
                "starting" is to be used when a test should behave like
index e39f1fe7c510e66f90fe9631ab23d19df6f04c55..0219b98868196da91860bfc996332645661c4a28 100644 (file)
@@ -1148,6 +1148,7 @@ Various:                                  *various-functions*
        getimstatus()           check if IME status is active
        interrupt()             interrupt script execution
        windowsversion()        get MS-Windows version
+       terminalprops()         properties of the terminal
 
        libcall()               call a function in an external library
        libcallnr()             idem, returning a number
index 1f53095101754452369e0cbbf1047c96d6e01b80..fe98636598d4404279acdc7cd0d17a5f5f345c92 100644 (file)
@@ -944,6 +944,7 @@ static funcentry_T global_functions[] =
     {"term_setsize",   3, 3, FEARG_1,    ret_void,     TERM_FUNC(f_term_setsize)},
     {"term_start",     1, 2, FEARG_1,    ret_number,   TERM_FUNC(f_term_start)},
     {"term_wait",      1, 2, FEARG_1,    ret_void,     TERM_FUNC(f_term_wait)},
+    {"terminalprops",  0, 0, 0,          ret_dict_string, f_terminalprops},
     {"test_alloc_fail",        3, 3, FEARG_1,    ret_void,     f_test_alloc_fail},
     {"test_autochdir", 0, 0, 0,          ret_void,     f_test_autochdir},
     {"test_feedinput", 1, 1, FEARG_1,    ret_void,     f_test_feedinput},
index b8fd231dfafe325a638262f1e8b8f64f50cf01d3..e5dcb7b65ab90be9c64715db19393aea64332090 100644 (file)
@@ -1839,6 +1839,7 @@ EXTERN int  disable_redraw_for_testing INIT(= FALSE);
 EXTERN int  ignore_redraw_flag_for_testing INIT(= FALSE);
 EXTERN int  nfa_fail_for_testing INIT(= FALSE);
 EXTERN int  no_query_mouse_for_testing INIT(= FALSE);
+EXTERN int  reset_term_props_on_termresponse INIT(= FALSE);
 
 EXTERN int  in_free_unref_items INIT(= FALSE);
 #endif
index f686a5fb5bc87a6d5150271af6b42faf4b854318..39e67e998793cb58d9c5efbcac63263287243b88 100644 (file)
@@ -407,6 +407,10 @@ main
     init_highlight(TRUE, FALSE); // set the default highlight groups
     TIME_MSG("init highlight");
 
+#if defined(FEAT_TERMRESPONSE)
+    init_term_props(TRUE);
+#endif
+
 #ifdef FEAT_EVAL
     // Set the break level after the terminal is initialized.
     debug_break_level = params.use_debug_break_level;
index 40934eae9ae64ffc1564c48d9dffcf9d1b9711a8..1b3780204be77377bf0463d3851d63626e9cd51d 100644 (file)
@@ -1,6 +1,8 @@
 /* term.c */
 guicolor_T termgui_get_color(char_u *name);
 guicolor_T termgui_mch_get_rgb(guicolor_T color);
+void init_term_props(int all);
+void f_terminalprops(typval_T *argvars, typval_T *rettv);
 void set_color_count(int nr);
 int set_termname(char_u *term);
 void getlinecol(long *cp, long *rp);
index 82b1126e7e4cf7f390c9971d88ef96156ee3f09b..e75fddb23af5a50594864ac1801b79c1d553bf5f 100644 (file)
@@ -1470,7 +1470,7 @@ static termprop_T term_props[TPR_COUNT];
  * When "all" is FALSE only set those that are detected from the version
  * response.
  */
-    static void
+    void
 init_term_props(int all)
 {
     int i;
@@ -1488,6 +1488,29 @@ init_term_props(int all)
        if (all || term_props[i].tpr_set_by_termresponse)
            term_props[i].tpr_status = TPR_UNKNOWN;
 }
+#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+    void
+f_terminalprops(typval_T *argvars UNUSED, typval_T *rettv)
+{
+# ifdef FEAT_TERMRESPONSE
+    int i;
+# endif
+
+    if (rettv_dict_alloc(rettv) != OK)
+       return;
+# ifdef FEAT_TERMRESPONSE
+    for (i = 0; i < TPR_COUNT; ++i)
+    {
+       char_u  value[2];
+
+       value[0] = term_props[i].tpr_status;
+       value[1] = NUL;
+       dict_add_string(rettv->vval.v_dict, term_props[i].tpr_name, value);
+    }
+# endif
+}
 #endif
 
     static struct builtin_term *
@@ -3676,8 +3699,6 @@ check_terminal_behavior(void)
 {
     int            did_send = FALSE;
 
-    init_term_props(TRUE);
-
     if (!can_get_termresponse() || starting != 0 || *T_U7 == NUL)
        return;
 
@@ -4516,7 +4537,8 @@ handle_version_response(int first, int *arg, int argc, char_u *tp)
 
     // Reset terminal properties that are set based on the termresponse.
     // Mainly useful for tests that send the termresponse multiple times.
-    init_term_props(FALSE);
+    // For testing all props can be reset.
+    init_term_props(reset_term_props_on_termresponse);
 
     // If this code starts with CSI, you can bet that the
     // terminal uses 8-bit codes.
index 86589b28d09e13b7d3612e4e22893a7a50ffd3c5..82f5f41be3bfd8c3437b2a8c82f6dead0db6052c 100644 (file)
@@ -922,6 +922,7 @@ endfunc
 func Test_xx01_term_style_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   " send the termresponse to trigger requesting the XT codes
   let seq = "\<Esc>[>41;337;0c"
@@ -932,7 +933,15 @@ func Test_xx01_term_style_response()
   call feedkeys(seq, 'Lx!')
   call assert_equal(seq, v:termstyleresp)
 
+  call assert_equal(#{
+        \ cursor_style: 'u',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'u',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   set t_RV=
+  call test_override('term_props', 0)
 endfunc
 
 " This checks the iTerm2 version response.
@@ -941,6 +950,7 @@ endfunc
 func Test_xx02_iTerm2_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   " Old versions of iTerm2 used a different style term response.
   set ttymouse=xterm
@@ -957,7 +967,15 @@ func Test_xx02_iTerm2_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('sgr', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'u',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   set t_RV=
+  call test_override('term_props', 0)
 endfunc
 
 " This checks the libvterm version response.
@@ -966,6 +984,7 @@ endfunc
 func Test_xx03_libvterm_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   set ttymouse=xterm
   call test_option_not_set('ttymouse')
@@ -974,7 +993,15 @@ func Test_xx03_libvterm_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('sgr', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'u',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   set t_RV=
+  call test_override('term_props', 0)
 endfunc
 
 " This checks the Mac Terminal.app version response.
@@ -983,6 +1010,7 @@ endfunc
 func Test_xx04_Mac_Terminal_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   set ttymouse=xterm
   call test_option_not_set('ttymouse')
@@ -991,10 +1019,18 @@ func Test_xx04_Mac_Terminal_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('sgr', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'y',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   " Reset is_not_xterm and is_mac_terminal.
   set t_RV=
   set term=xterm
   set t_RV=x
+  call test_override('term_props', 0)
 endfunc
 
 " This checks the mintty version response.
@@ -1003,6 +1039,7 @@ endfunc
 func Test_xx05_mintty_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   set ttymouse=xterm
   call test_option_not_set('ttymouse')
@@ -1011,7 +1048,15 @@ func Test_xx05_mintty_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('sgr', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'y',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   set t_RV=
+  call test_override('term_props', 0)
 endfunc
 
 " This checks the screen version response.
@@ -1020,6 +1065,7 @@ endfunc
 func Test_xx06_screen_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   " Old versions of screen don't support SGR mouse mode.
   set ttymouse=xterm
@@ -1037,7 +1083,15 @@ func Test_xx06_screen_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('sgr', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'n',
+        \ underline_rgb: 'y',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   set t_RV=
+  call test_override('term_props', 0)
 endfunc
 
 " This checks the xterm version response.
@@ -1046,6 +1100,7 @@ endfunc
 func Test_xx07_xterm_response()
   " Termresponse is only parsed when t_RV is not empty.
   set t_RV=x
+  call test_override('term_props', 1)
 
   " Do Terminal.app first to check that is_mac_terminal is reset.
   set ttymouse=xterm
@@ -1066,6 +1121,13 @@ func Test_xx07_xterm_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('xterm', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'y',
+        \ mouse: 'u'
+        \ }, terminalprops())
+
   " xterm >= 95 < 277 "xterm2"
   set ttymouse=xterm
   call test_option_not_set('ttymouse')
@@ -1074,6 +1136,13 @@ func Test_xx07_xterm_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('xterm2', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'u',
+        \ mouse: '2'
+        \ }, terminalprops())
+
   " xterm >= 277: "sgr"
   set ttymouse=xterm
   call test_option_not_set('ttymouse')
@@ -1082,7 +1151,30 @@ func Test_xx07_xterm_response()
   call assert_equal(seq, v:termresponse)
   call assert_equal('sgr', &ttymouse)
 
+  call assert_equal(#{
+        \ cursor_style: 'n',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'u',
+        \ mouse: 's'
+        \ }, terminalprops())
+
+  " xterm >= 279: "sgr" and cursor_style not reset
+  set ttymouse=xterm
+  call test_option_not_set('ttymouse')
+  let seq = "\<Esc>[>0;279;0c"
+  call feedkeys(seq, 'Lx!')
+  call assert_equal(seq, v:termresponse)
+  call assert_equal('sgr', &ttymouse)
+
+  call assert_equal(#{
+        \ cursor_style: 'u',
+        \ cursor_blink_mode: 'u',
+        \ underline_rgb: 'u',
+        \ mouse: 's'
+        \ }, terminalprops())
+
   set t_RV=
+  call test_override('term_props', 0)
 endfunc
 
 func Test_get_termcode()
index c01ae3db7752f21328bc35bece4c05a463f25109..83e3fe4e3c720442a55be88306f8f8c5861a5dff 100644 (file)
@@ -854,6 +854,8 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
            no_query_mouse_for_testing = val;
        else if (STRCMP(name, (char_u *)"no_wait_return") == 0)
            no_wait_return = val;
+       else if (STRCMP(name, (char_u *)"term_props") == 0)
+           reset_term_props_on_termresponse = val;
        else if (STRCMP(name, (char_u *)"ALL") == 0)
        {
            disable_char_avail_for_testing = FALSE;
@@ -861,6 +863,7 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
            ignore_redraw_flag_for_testing = FALSE;
            nfa_fail_for_testing = FALSE;
            no_query_mouse_for_testing = FALSE;
+           reset_term_props_on_termresponse = FALSE;
            if (save_starting >= 0)
            {
                starting = save_starting;
index 1c660ed62f15e3305602c598ac8764ea14d81a90..052f030e5691e6154cd2e2920899625f32afc761 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    970,
 /**/
     969,
 /**/