1
0
forked from aniani/vim

patch 8.2.0970: terminal properties are not available in Vim script

Problem:    Terminal properties are not available in Vim script.
Solution:   Add the terminalprops() function.
This commit is contained in:
Bram Moolenaar
2020-06-13 15:47:25 +02:00
parent 4a021dfbee
commit 0c0eddd3dd
11 changed files with 172 additions and 5 deletions

View 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|

View 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

View 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

View 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},

View 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

View 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;

View 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);

View 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.

View 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()

View 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;

View File

@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
970,
/**/
969,
/**/