mirror of
https://github.com/zoriya/vim.git
synced 2025-12-17 04:35:18 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
753289f9bf | ||
|
|
be0b72977f | ||
|
|
f6d9f96b2d | ||
|
|
33d66bd9fa | ||
|
|
6c4d12c527 | ||
|
|
285f243e50 | ||
|
|
77f7474d08 | ||
|
|
829aa64cf5 | ||
|
|
d2c45a1964 | ||
|
|
ec0e07a324 | ||
|
|
6d0826dfbb | ||
|
|
5830232c02 | ||
|
|
3f9a1ff141 | ||
|
|
740c433c59 | ||
|
|
0cbba82359 | ||
|
|
b109bb4e12 | ||
|
|
eef0531621 | ||
|
|
37819ed540 | ||
|
|
5983d50247 | ||
|
|
b241208a13 | ||
|
|
edbc0d46cf | ||
|
|
8efa026a25 | ||
|
|
ce1c32780a | ||
|
|
37b9b81997 | ||
|
|
0aed9a2e2e | ||
|
|
d6a7b3e6bb | ||
|
|
dc926dd0dd | ||
|
|
77ac9b5c62 | ||
|
|
93c92eff26 | ||
|
|
fc8bec0be4 | ||
|
|
3eee06e7d4 |
@@ -1,4 +1,4 @@
|
|||||||
*terminal.txt* For Vim version 8.0. Last change: 2017 Aug 12
|
*terminal.txt* For Vim version 8.0. Last change: 2017 Aug 20
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -102,10 +102,9 @@ Syntax ~
|
|||||||
parentheses. E.g. if "gdb" exists the second terminal
|
parentheses. E.g. if "gdb" exists the second terminal
|
||||||
buffer will use "!gdb (1)".
|
buffer will use "!gdb (1)".
|
||||||
|
|
||||||
If [range] is given it is used for the terminal size.
|
If [range] is given the specified lines are used as
|
||||||
One number specifies the number of rows. Unless the
|
input for the job. It will not be possible to type
|
||||||
"vertical" modifier is used, then it is the number of
|
keys in the terminal window.
|
||||||
columns.
|
|
||||||
|
|
||||||
Two comma separated numbers are used as "rows,cols".
|
Two comma separated numbers are used as "rows,cols".
|
||||||
E.g. `:24,80gdb` opens a terminal with 24 rows and 80
|
E.g. `:24,80gdb` opens a terminal with 24 rows and 80
|
||||||
@@ -125,6 +124,10 @@ Syntax ~
|
|||||||
cannot be |abandon|ed.
|
cannot be |abandon|ed.
|
||||||
++hidden Open the terminal in a hidden buffer,
|
++hidden Open the terminal in a hidden buffer,
|
||||||
no window will be used.
|
no window will be used.
|
||||||
|
++rows={height} Use {height} for the terminal window
|
||||||
|
height.
|
||||||
|
++cols={width} Use {width} for the terminal window
|
||||||
|
width.
|
||||||
|
|
||||||
If you want to use more options use the |term_start()|
|
If you want to use more options use the |term_start()|
|
||||||
function.
|
function.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
" These commands create the option window.
|
" These commands create the option window.
|
||||||
"
|
"
|
||||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
" Last Change: 2017 Aug 11
|
" Last Change: 2017 Aug 19
|
||||||
|
|
||||||
" If there already is an option window, jump to that one.
|
" If there already is an option window, jump to that one.
|
||||||
let buf = bufnr('option-window')
|
let buf = bufnr('option-window')
|
||||||
@@ -510,6 +510,10 @@ if has("terminal")
|
|||||||
call append("$", "termkey\tkey that precedes Vim commands in a terminal window")
|
call append("$", "termkey\tkey that precedes Vim commands in a terminal window")
|
||||||
call append("$", "\t(local to window)")
|
call append("$", "\t(local to window)")
|
||||||
call <SID>OptionL("tk")
|
call <SID>OptionL("tk")
|
||||||
|
if exists("&winptydll")
|
||||||
|
call append("$", "winptydll\tname of the winpty dynamic library")
|
||||||
|
call <SID>OptionG("winptydll", &winptydll)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -340,6 +340,7 @@ endif
|
|||||||
# TCL_VER=[TCL version, eg 83, 84] (default is 86)
|
# TCL_VER=[TCL version, eg 83, 84] (default is 86)
|
||||||
# TCL_VER_LONG=[Tcl version, eg 8.3] (default is 8.6)
|
# TCL_VER_LONG=[Tcl version, eg 8.3] (default is 8.6)
|
||||||
# You must set TCL_VER_LONG when you set TCL_VER.
|
# You must set TCL_VER_LONG when you set TCL_VER.
|
||||||
|
# TCL_DLL=[TCL dll name, eg tcl86.dll] (default is tcl86.dll)
|
||||||
ifdef TCL
|
ifdef TCL
|
||||||
ifndef DYNAMIC_TCL
|
ifndef DYNAMIC_TCL
|
||||||
DYNAMIC_TCL=yes
|
DYNAMIC_TCL=yes
|
||||||
@@ -350,6 +351,9 @@ endif
|
|||||||
ifndef TCL_VER_LONG
|
ifndef TCL_VER_LONG
|
||||||
TCL_VER_LONG = 8.6
|
TCL_VER_LONG = 8.6
|
||||||
endif
|
endif
|
||||||
|
ifndef TCL_DLL
|
||||||
|
TCL_DLL = tcl$(TCL_VER).dll
|
||||||
|
endif
|
||||||
TCLINC += -I$(TCL)/include
|
TCLINC += -I$(TCL)/include
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -526,7 +530,7 @@ endif
|
|||||||
ifdef TCL
|
ifdef TCL
|
||||||
CFLAGS += -DFEAT_TCL $(TCLINC)
|
CFLAGS += -DFEAT_TCL $(TCLINC)
|
||||||
ifeq (yes, $(DYNAMIC_TCL))
|
ifeq (yes, $(DYNAMIC_TCL))
|
||||||
CFLAGS += -DDYNAMIC_TCL -DDYNAMIC_TCL_DLL=\"tcl$(TCL_VER).dll\" -DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\"
|
CFLAGS += -DDYNAMIC_TCL -DDYNAMIC_TCL_DLL=\"$(TCL_DLL)\" -DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -971,7 +975,11 @@ $(OUTDIR)/terminal.o: terminal.c $(INCL) $(TERM_DEPS)
|
|||||||
$(CC) -c $(CFLAGS) terminal.c -o $(OUTDIR)/terminal.o
|
$(CC) -c $(CFLAGS) terminal.c -o $(OUTDIR)/terminal.o
|
||||||
|
|
||||||
|
|
||||||
CCCTERM = $(CC) -c $(CFLAGS) -Ilibvterm/include -DINLINE="" -DVSNPRINTF=vim_vsnprintf
|
CCCTERM = $(CC) -c $(CFLAGS) -Ilibvterm/include -DINLINE="" \
|
||||||
|
-DVSNPRINTF=vim_vsnprintf \
|
||||||
|
-DIS_COMBINING_FUNCTION=utf_iscomposing_uint \
|
||||||
|
-DWCWIDTH_FUNCTION=utf_uint2cells
|
||||||
|
|
||||||
$(OUTDIR)/term_encoding.o: libvterm/src/encoding.c $(TERM_DEPS)
|
$(OUTDIR)/term_encoding.o: libvterm/src/encoding.c $(TERM_DEPS)
|
||||||
$(CCCTERM) libvterm/src/encoding.c -o $@
|
$(CCCTERM) libvterm/src/encoding.c -o $@
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
# TCL_VER=[Tcl version, e.g. 80, 83] (default is 86)
|
# TCL_VER=[Tcl version, e.g. 80, 83] (default is 86)
|
||||||
# TCL_VER_LONG=[Tcl version, eg 8.3] (default is 8.6)
|
# TCL_VER_LONG=[Tcl version, eg 8.3] (default is 8.6)
|
||||||
# You must set TCL_VER_LONG when you set TCL_VER.
|
# You must set TCL_VER_LONG when you set TCL_VER.
|
||||||
|
# TCL_DLL=[Tcl dll name, e.g. tcl86.dll] (default is tcl86.dll)
|
||||||
#
|
#
|
||||||
# Cscope support: CSCOPE=yes
|
# Cscope support: CSCOPE=yes
|
||||||
#
|
#
|
||||||
@@ -832,7 +833,9 @@ TCL_VER_LONG = 8.6
|
|||||||
!message Tcl requested (version $(TCL_VER)) - root dir is "$(TCL)"
|
!message Tcl requested (version $(TCL_VER)) - root dir is "$(TCL)"
|
||||||
!if "$(DYNAMIC_TCL)" == "yes"
|
!if "$(DYNAMIC_TCL)" == "yes"
|
||||||
!message Tcl DLL will be loaded dynamically
|
!message Tcl DLL will be loaded dynamically
|
||||||
|
!ifndef TCL_DLL
|
||||||
TCL_DLL = tcl$(TCL_VER).dll
|
TCL_DLL = tcl$(TCL_VER).dll
|
||||||
|
!endif
|
||||||
CFLAGS = $(CFLAGS) -DFEAT_TCL -DDYNAMIC_TCL -DDYNAMIC_TCL_DLL=\"$(TCL_DLL)\" \
|
CFLAGS = $(CFLAGS) -DFEAT_TCL -DDYNAMIC_TCL -DDYNAMIC_TCL_DLL=\"$(TCL_DLL)\" \
|
||||||
-DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\"
|
-DDYNAMIC_TCL_VER=\"$(TCL_VER_LONG)\"
|
||||||
TCL_OBJ = $(OUTDIR)\if_tcl.obj
|
TCL_OBJ = $(OUTDIR)\if_tcl.obj
|
||||||
@@ -1474,7 +1477,12 @@ $(OUTDIR)/dimm_i.obj: $(OUTDIR) dimm_i.c $(INCL)
|
|||||||
$(OUTDIR)/glbl_ime.obj: $(OUTDIR) glbl_ime.cpp dimm.h $(INCL)
|
$(OUTDIR)/glbl_ime.obj: $(OUTDIR) glbl_ime.cpp dimm.h $(INCL)
|
||||||
|
|
||||||
|
|
||||||
CCCTERM = $(CC) $(CFLAGS) -Ilibvterm/include -DINLINE="" -DVSNPRINTF=vim_vsnprintf -D_CRT_SECURE_NO_WARNINGS
|
CCCTERM = $(CC) $(CFLAGS) -Ilibvterm/include -DINLINE="" \
|
||||||
|
-DVSNPRINTF=vim_vsnprintf \
|
||||||
|
-DIS_COMBINING_FUNCTION=utf_iscomposing_uint \
|
||||||
|
-DWCWIDTH_FUNCTION=utf_uint2cells \
|
||||||
|
-D_CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
$(OUTDIR)/term_encoding.obj: $(OUTDIR) libvterm/src/encoding.c $(TERM_DEPS)
|
$(OUTDIR)/term_encoding.obj: $(OUTDIR) libvterm/src/encoding.c $(TERM_DEPS)
|
||||||
$(CCCTERM) -Fo$@ libvterm/src/encoding.c
|
$(CCCTERM) -Fo$@ libvterm/src/encoding.c
|
||||||
|
|
||||||
|
|||||||
@@ -3296,7 +3296,11 @@ objects/channel.o: channel.c
|
|||||||
Makefile:
|
Makefile:
|
||||||
@echo The name of the makefile MUST be "Makefile" (with capital M)!!!!
|
@echo The name of the makefile MUST be "Makefile" (with capital M)!!!!
|
||||||
|
|
||||||
CCCTERM = $(CCC) -Ilibvterm/include -DINLINE="" -DVSNPRINTF=vim_vsnprintf
|
CCCTERM = $(CCC) -Ilibvterm/include -DINLINE="" \
|
||||||
|
-DVSNPRINTF=vim_vsnprintf \
|
||||||
|
-DIS_COMBINING_FUNCTION=utf_iscomposing_uint \
|
||||||
|
-DWCWIDTH_FUNCTION=utf_uint2cells
|
||||||
|
|
||||||
objects/term_encoding.o: libvterm/src/encoding.c $(TERM_DEPS)
|
objects/term_encoding.o: libvterm/src/encoding.c $(TERM_DEPS)
|
||||||
$(CCCTERM) -o $@ libvterm/src/encoding.c
|
$(CCCTERM) -o $@ libvterm/src/encoding.c
|
||||||
|
|
||||||
|
|||||||
@@ -3559,7 +3559,7 @@ channel_set_nonblock(channel_T *channel, ch_part_T part)
|
|||||||
|
|
||||||
ioctlsocket(fd, FIONBIO, &val);
|
ioctlsocket(fd, FIONBIO, &val);
|
||||||
#else
|
#else
|
||||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
(void)fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||||
#endif
|
#endif
|
||||||
ch_part->ch_nonblocking = TRUE;
|
ch_part->ch_nonblocking = TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1484,8 +1484,8 @@ EX(CMD_tearoff, "tearoff", ex_tearoff,
|
|||||||
NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN,
|
NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EX(CMD_terminal, "terminal", ex_terminal,
|
EX(CMD_terminal, "terminal", ex_terminal,
|
||||||
RANGE|NOTADR|BANG|FILES|TRLBAR|CMDWIN,
|
RANGE|BANG|FILES|TRLBAR|CMDWIN,
|
||||||
ADDR_OTHER),
|
ADDR_LINES),
|
||||||
EX(CMD_tfirst, "tfirst", ex_tag,
|
EX(CMD_tfirst, "tfirst", ex_tag,
|
||||||
RANGE|NOTADR|BANG|TRLBAR|ZEROR,
|
RANGE|NOTADR|BANG|TRLBAR|ZEROR,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
|
|||||||
@@ -1981,9 +1981,7 @@ dialog_changed(
|
|||||||
buf_T *buf2;
|
buf_T *buf2;
|
||||||
exarg_T ea;
|
exarg_T ea;
|
||||||
|
|
||||||
dialog_msg(buff, _("Save changes to \"%s\"?"),
|
dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname);
|
||||||
(buf->b_fname != NULL) ?
|
|
||||||
buf->b_fname : (char_u *)_("Untitled"));
|
|
||||||
if (checkall)
|
if (checkall)
|
||||||
ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
|
ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1269,8 +1269,10 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* +terminal ":terminal" command. Runs a terminal in a window.
|
* +terminal ":terminal" command. Runs a terminal in a window.
|
||||||
|
* requires +channel and +multibyte
|
||||||
*/
|
*/
|
||||||
#if !defined(FEAT_JOB_CHANNEL) && defined(FEAT_TERMINAL)
|
#if defined(FEAT_TERMINAL) && \
|
||||||
|
!(defined(FEAT_JOB_CHANNEL) && defined(FEAT_MBYTE))
|
||||||
# undef FEAT_TERMINAL
|
# undef FEAT_TERMINAL
|
||||||
#endif
|
#endif
|
||||||
#if defined(FEAT_TERMINAL) && !defined(CURSOR_SHAPE)
|
#if defined(FEAT_TERMINAL) && !defined(CURSOR_SHAPE)
|
||||||
|
|||||||
@@ -1370,7 +1370,8 @@ retry:
|
|||||||
* Decrypt the read bytes. This is done before checking for
|
* Decrypt the read bytes. This is done before checking for
|
||||||
* EOF because the crypt layer may be buffering.
|
* EOF because the crypt layer may be buffering.
|
||||||
*/
|
*/
|
||||||
if (cryptkey != NULL && size > 0)
|
if (cryptkey != NULL && curbuf->b_cryptstate != NULL
|
||||||
|
&& size > 0)
|
||||||
{
|
{
|
||||||
if (crypt_works_inplace(curbuf->b_cryptstate))
|
if (crypt_works_inplace(curbuf->b_cryptstate))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(IS_COMBINING_FUNCTION) || !defined(WCWIDTH_FUNCTION)
|
||||||
struct interval {
|
struct interval {
|
||||||
int first;
|
int first;
|
||||||
int last;
|
int last;
|
||||||
@@ -126,7 +127,6 @@ static const struct interval combining[] = {
|
|||||||
{ 0xE0100, 0xE01EF }
|
{ 0xE0100, 0xE01EF }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* auxiliary function for binary search in interval table */
|
/* auxiliary function for binary search in interval table */
|
||||||
static int bisearch(uint32_t ucs, const struct interval *table, int max) {
|
static int bisearch(uint32_t ucs, const struct interval *table, int max) {
|
||||||
int min = 0;
|
int min = 0;
|
||||||
@@ -146,6 +146,7 @@ static int bisearch(uint32_t ucs, const struct interval *table, int max) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The following two functions define the column width of an ISO 10646
|
/* The following two functions define the column width of an ISO 10646
|
||||||
@@ -180,6 +181,11 @@ static int bisearch(uint32_t ucs, const struct interval *table, int max) {
|
|||||||
* in ISO 10646.
|
* in ISO 10646.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WCWIDTH_FUNCTION
|
||||||
|
/* use a provided wcwidth() function */
|
||||||
|
int WCWIDTH_FUNCTION(uint32_t ucs);
|
||||||
|
#else
|
||||||
|
# define WCWIDTH_FUNCTION mk_wcwidth
|
||||||
|
|
||||||
static int mk_wcwidth(uint32_t ucs)
|
static int mk_wcwidth(uint32_t ucs)
|
||||||
{
|
{
|
||||||
@@ -211,6 +217,7 @@ static int mk_wcwidth(uint32_t ucs)
|
|||||||
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
|
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
|
||||||
(ucs >= 0x30000 && ucs <= 0x3fffd)));
|
(ucs >= 0x30000 && ucs <= 0x3fffd)));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0 /* unused */
|
#if 0 /* unused */
|
||||||
static int mk_wcswidth(const uint32_t *pwcs, size_t n)
|
static int mk_wcswidth(const uint32_t *pwcs, size_t n)
|
||||||
@@ -317,15 +324,28 @@ static int mk_wcswidth_cjk(const uint32_t *pwcs, size_t n)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef IS_COMBINING_FUNCTION
|
||||||
|
/* Use a provided is_combining() function. */
|
||||||
|
int IS_COMBINING_FUNCTION(uint32_t codepoint);
|
||||||
|
#else
|
||||||
|
# define IS_COMBINING_FUNCTION vterm_is_combining
|
||||||
|
static int
|
||||||
|
vterm_is_combining(uint32_t codepoint)
|
||||||
|
{
|
||||||
|
return bisearch(codepoint, combining, sizeof(combining) / sizeof(struct interval) - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ################################
|
/* ################################
|
||||||
* ### The rest added by Paul Evans */
|
* ### The rest added by Paul Evans */
|
||||||
|
|
||||||
INTERNAL int vterm_unicode_width(uint32_t codepoint)
|
INTERNAL int vterm_unicode_width(uint32_t codepoint)
|
||||||
{
|
{
|
||||||
return mk_wcwidth(codepoint);
|
return WCWIDTH_FUNCTION(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL int vterm_unicode_is_combining(uint32_t codepoint)
|
INTERNAL int vterm_unicode_is_combining(uint32_t codepoint)
|
||||||
{
|
{
|
||||||
return bisearch(codepoint, combining, sizeof(combining) / sizeof(struct interval) - 1);
|
return IS_COMBINING_FUNCTION(codepoint);
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/mbyte.c
22
src/mbyte.c
@@ -1395,6 +1395,17 @@ static struct interval ambiguous[] =
|
|||||||
{0x100000, 0x10fffd}
|
{0x100000, 0x10fffd}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(FEAT_TERMINAL) || defined(PROTO)
|
||||||
|
/*
|
||||||
|
* utf_char2cells() with different argument type for libvterm.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
utf_uint2cells(uint32_t c)
|
||||||
|
{
|
||||||
|
return utf_char2cells((int)c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For UTF-8 character "c" return 2 for a double-width character, 1 for others.
|
* For UTF-8 character "c" return 2 for a double-width character, 1 for others.
|
||||||
* Returns 4 or 6 for an unprintable character.
|
* Returns 4 or 6 for an unprintable character.
|
||||||
@@ -2296,6 +2307,17 @@ utf_char2bytes(int c, char_u *buf)
|
|||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(FEAT_TERMINAL) || defined(PROTO)
|
||||||
|
/*
|
||||||
|
* utf_iscomposing() with different argument type for libvterm.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
utf_iscomposing_uint(uint32_t c)
|
||||||
|
{
|
||||||
|
return utf_iscomposing((int)c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "c" is a composing UTF-8 character. This means it will be
|
* Return TRUE if "c" is a composing UTF-8 character. This means it will be
|
||||||
* drawn on top of the preceding character.
|
* drawn on top of the preceding character.
|
||||||
|
|||||||
57
src/option.c
57
src/option.c
@@ -3157,6 +3157,8 @@ static struct vimoption options[] =
|
|||||||
p_term("t_AL", T_CAL)
|
p_term("t_AL", T_CAL)
|
||||||
p_term("t_al", T_AL)
|
p_term("t_al", T_AL)
|
||||||
p_term("t_bc", T_BC)
|
p_term("t_bc", T_BC)
|
||||||
|
p_term("t_BE", T_BE)
|
||||||
|
p_term("t_BD", T_BD)
|
||||||
p_term("t_cd", T_CD)
|
p_term("t_cd", T_CD)
|
||||||
p_term("t_ce", T_CE)
|
p_term("t_ce", T_CE)
|
||||||
p_term("t_cl", T_CL)
|
p_term("t_cl", T_CL)
|
||||||
@@ -3173,12 +3175,11 @@ static struct vimoption options[] =
|
|||||||
p_term("t_db", T_DB)
|
p_term("t_db", T_DB)
|
||||||
p_term("t_DL", T_CDL)
|
p_term("t_DL", T_CDL)
|
||||||
p_term("t_dl", T_DL)
|
p_term("t_dl", T_DL)
|
||||||
|
p_term("t_EC", T_CEC)
|
||||||
p_term("t_EI", T_CEI)
|
p_term("t_EI", T_CEI)
|
||||||
p_term("t_fs", T_FS)
|
p_term("t_fs", T_FS)
|
||||||
|
p_term("t_GP", T_CGP)
|
||||||
p_term("t_IE", T_CIE)
|
p_term("t_IE", T_CIE)
|
||||||
p_term("t_SC", T_CSC)
|
|
||||||
p_term("t_EC", T_CEC)
|
|
||||||
p_term("t_SH", T_CSH)
|
|
||||||
p_term("t_IS", T_CIS)
|
p_term("t_IS", T_CIS)
|
||||||
p_term("t_ke", T_KE)
|
p_term("t_ke", T_KE)
|
||||||
p_term("t_ks", T_KS)
|
p_term("t_ks", T_KS)
|
||||||
@@ -3192,10 +3193,13 @@ static struct vimoption options[] =
|
|||||||
p_term("t_op", T_OP)
|
p_term("t_op", T_OP)
|
||||||
p_term("t_RB", T_RBG)
|
p_term("t_RB", T_RBG)
|
||||||
p_term("t_RI", T_CRI)
|
p_term("t_RI", T_CRI)
|
||||||
|
p_term("t_RS", T_CRS)
|
||||||
p_term("t_RV", T_CRV)
|
p_term("t_RV", T_CRV)
|
||||||
p_term("t_Sb", T_CSB)
|
p_term("t_Sb", T_CSB)
|
||||||
|
p_term("t_SC", T_CSC)
|
||||||
p_term("t_se", T_SE)
|
p_term("t_se", T_SE)
|
||||||
p_term("t_Sf", T_CSF)
|
p_term("t_Sf", T_CSF)
|
||||||
|
p_term("t_SH", T_CSH)
|
||||||
p_term("t_SI", T_CSI)
|
p_term("t_SI", T_CSI)
|
||||||
p_term("t_so", T_SO)
|
p_term("t_so", T_SO)
|
||||||
p_term("t_SR", T_CSR)
|
p_term("t_SR", T_CSR)
|
||||||
@@ -3210,9 +3214,9 @@ static struct vimoption options[] =
|
|||||||
p_term("t_vb", T_VB)
|
p_term("t_vb", T_VB)
|
||||||
p_term("t_ve", T_VE)
|
p_term("t_ve", T_VE)
|
||||||
p_term("t_vi", T_VI)
|
p_term("t_vi", T_VI)
|
||||||
|
p_term("t_VS", T_CVS)
|
||||||
p_term("t_vs", T_VS)
|
p_term("t_vs", T_VS)
|
||||||
p_term("t_WP", T_CWP)
|
p_term("t_WP", T_CWP)
|
||||||
p_term("t_GP", T_CGP)
|
|
||||||
p_term("t_WS", T_CWS)
|
p_term("t_WS", T_CWS)
|
||||||
p_term("t_xn", T_XN)
|
p_term("t_xn", T_XN)
|
||||||
p_term("t_xs", T_XS)
|
p_term("t_xs", T_XS)
|
||||||
@@ -3220,8 +3224,6 @@ static struct vimoption options[] =
|
|||||||
p_term("t_ZR", T_CZR)
|
p_term("t_ZR", T_CZR)
|
||||||
p_term("t_8f", T_8F)
|
p_term("t_8f", T_8F)
|
||||||
p_term("t_8b", T_8B)
|
p_term("t_8b", T_8B)
|
||||||
p_term("t_BE", T_BE)
|
|
||||||
p_term("t_BD", T_BD)
|
|
||||||
|
|
||||||
/* terminal key codes are not in here */
|
/* terminal key codes are not in here */
|
||||||
|
|
||||||
@@ -4349,8 +4351,6 @@ trigger_optionsset_string(
|
|||||||
(char_u *)options[opt_idx].fullname, NULL, FALSE, NULL);
|
(char_u *)options[opt_idx].fullname, NULL, FALSE, NULL);
|
||||||
reset_v_option_vars();
|
reset_v_option_vars();
|
||||||
}
|
}
|
||||||
vim_free(oldval);
|
|
||||||
vim_free(newval);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -4841,6 +4841,16 @@ do_set(
|
|||||||
/* The old value is kept until we are sure that the
|
/* The old value is kept until we are sure that the
|
||||||
* new value is valid. */
|
* new value is valid. */
|
||||||
oldval = *(char_u **)varp;
|
oldval = *(char_u **)varp;
|
||||||
|
|
||||||
|
/* When setting the local value of a global
|
||||||
|
* option, the old value may be the global value. */
|
||||||
|
if (((int)options[opt_idx].indir & PV_BOTH)
|
||||||
|
&& (opt_flags & OPT_LOCAL))
|
||||||
|
origval = *(char_u **)get_varp(
|
||||||
|
&options[opt_idx]);
|
||||||
|
else
|
||||||
|
origval = oldval;
|
||||||
|
|
||||||
if (nextchar == '&') /* set to default val */
|
if (nextchar == '&') /* set to default val */
|
||||||
{
|
{
|
||||||
newval = options[opt_idx].def_val[
|
newval = options[opt_idx].def_val[
|
||||||
@@ -4917,6 +4927,8 @@ do_set(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vim_free(oldval);
|
vim_free(oldval);
|
||||||
|
if (origval == oldval)
|
||||||
|
origval = *(char_u **)varp;
|
||||||
oldval = *(char_u **)varp;
|
oldval = *(char_u **)varp;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -4955,15 +4967,6 @@ do_set(
|
|||||||
++arg;
|
++arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When setting the local value of a global
|
|
||||||
* option, the old value may be the global value. */
|
|
||||||
if (((int)options[opt_idx].indir & PV_BOTH)
|
|
||||||
&& (opt_flags & OPT_LOCAL))
|
|
||||||
origval = *(char_u **)get_varp(
|
|
||||||
&options[opt_idx]);
|
|
||||||
else
|
|
||||||
origval = oldval;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the new string into allocated memory.
|
* Copy the new string into allocated memory.
|
||||||
* Can't use set_string_option_direct(), because
|
* Can't use set_string_option_direct(), because
|
||||||
@@ -5167,7 +5170,9 @@ do_set(
|
|||||||
new_value_alloced = TRUE;
|
new_value_alloced = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the new value. */
|
/*
|
||||||
|
* Set the new value.
|
||||||
|
*/
|
||||||
*(char_u **)(varp) = newval;
|
*(char_u **)(varp) = newval;
|
||||||
|
|
||||||
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
||||||
@@ -5193,20 +5198,17 @@ do_set(
|
|||||||
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
|
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
|
||||||
new_value_alloced, oldval, errbuf, opt_flags);
|
new_value_alloced, oldval, errbuf, opt_flags);
|
||||||
|
|
||||||
/* If error detected, print the error message. */
|
|
||||||
if (errmsg != NULL)
|
|
||||||
{
|
|
||||||
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
||||||
|
if (errmsg == NULL)
|
||||||
|
trigger_optionsset_string(opt_idx, opt_flags,
|
||||||
|
saved_origval, saved_newval);
|
||||||
vim_free(saved_origval);
|
vim_free(saved_origval);
|
||||||
vim_free(saved_newval);
|
vim_free(saved_newval);
|
||||||
#endif
|
#endif
|
||||||
|
/* If error detected, print the error message. */
|
||||||
|
if (errmsg != NULL)
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
|
||||||
trigger_optionsset_string(opt_idx, opt_flags,
|
|
||||||
saved_origval, saved_newval);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else /* key code option */
|
else /* key code option */
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
@@ -6012,8 +6014,11 @@ set_string_option(
|
|||||||
|
|
||||||
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
||||||
/* call autocommand after handling side effects */
|
/* call autocommand after handling side effects */
|
||||||
|
if (r == NULL)
|
||||||
trigger_optionsset_string(opt_idx, opt_flags,
|
trigger_optionsset_string(opt_idx, opt_flags,
|
||||||
saved_oldval, saved_newval);
|
saved_oldval, saved_newval);
|
||||||
|
vim_free(saved_oldval);
|
||||||
|
vim_free(saved_newval);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -4340,6 +4340,7 @@ mch_call_shell(
|
|||||||
|
|
||||||
# define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
|
# define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
|
||||||
127, some shells use that already */
|
127, some shells use that already */
|
||||||
|
# define OPEN_NULL_FAILED 123 /* Exit code if /dev/null can't be opened */
|
||||||
|
|
||||||
char_u *newcmd;
|
char_u *newcmd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@@ -5238,6 +5239,7 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
|
|||||||
int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE;
|
int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE;
|
||||||
int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE;
|
int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE;
|
||||||
int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE;
|
int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE;
|
||||||
|
int use_buffer_for_in = options->jo_io[PART_IN] == JIO_BUFFER;
|
||||||
int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
|
int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
|
||||||
SIGSET_DECL(curset)
|
SIGSET_DECL(curset)
|
||||||
|
|
||||||
@@ -5247,7 +5249,10 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
|
|||||||
/* default is to fail */
|
/* default is to fail */
|
||||||
job->jv_status = JOB_FAILED;
|
job->jv_status = JOB_FAILED;
|
||||||
|
|
||||||
if (options->jo_pty)
|
if (options->jo_pty
|
||||||
|
&& (!(use_file_for_in || use_null_for_in)
|
||||||
|
|| !(use_file_for_in || use_null_for_out)
|
||||||
|
|| !(use_out_for_err || use_file_for_err || use_null_for_err)))
|
||||||
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_name);
|
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_name);
|
||||||
|
|
||||||
/* TODO: without the channel feature connect the child to /dev/null? */
|
/* TODO: without the channel feature connect the child to /dev/null? */
|
||||||
@@ -5263,7 +5268,11 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!use_null_for_in && pty_master_fd < 0 && pipe(fd_in) < 0)
|
else
|
||||||
|
/* When writing buffer lines to the input don't use the pty, so that
|
||||||
|
* the pipe can be closed when all lines were written. */
|
||||||
|
if (!use_null_for_in && (pty_master_fd < 0 || use_buffer_for_in)
|
||||||
|
&& pipe(fd_in) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (use_file_for_out)
|
if (use_file_for_out)
|
||||||
@@ -5361,7 +5370,14 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (use_null_for_in || use_null_for_out || use_null_for_err)
|
if (use_null_for_in || use_null_for_out || use_null_for_err)
|
||||||
|
{
|
||||||
null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
|
null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
|
||||||
|
if (null_fd < 0)
|
||||||
|
{
|
||||||
|
perror("opening /dev/null failed");
|
||||||
|
_exit(OPEN_NULL_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pty_slave_fd >= 0)
|
if (pty_slave_fd >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ int latin_char2len(int c);
|
|||||||
int latin_char2bytes(int c, char_u *buf);
|
int latin_char2bytes(int c, char_u *buf);
|
||||||
int latin_ptr2len(char_u *p);
|
int latin_ptr2len(char_u *p);
|
||||||
int latin_ptr2len_len(char_u *p, int size);
|
int latin_ptr2len_len(char_u *p, int size);
|
||||||
|
int utf_uint2cells(uint32_t c);
|
||||||
int utf_char2cells(int c);
|
int utf_char2cells(int c);
|
||||||
int latin_ptr2cells(char_u *p);
|
int latin_ptr2cells(char_u *p);
|
||||||
int utf_ptr2cells(char_u *p);
|
int utf_ptr2cells(char_u *p);
|
||||||
@@ -37,6 +38,7 @@ int utfc_ptr2len(char_u *p);
|
|||||||
int utfc_ptr2len_len(char_u *p, int size);
|
int utfc_ptr2len_len(char_u *p, int size);
|
||||||
int utf_char2len(int c);
|
int utf_char2len(int c);
|
||||||
int utf_char2bytes(int c, char_u *buf);
|
int utf_char2bytes(int c, char_u *buf);
|
||||||
|
int utf_iscomposing_uint(uint32_t c);
|
||||||
int utf_iscomposing(int c);
|
int utf_iscomposing(int c);
|
||||||
int utf_printable(int c);
|
int utf_printable(int c);
|
||||||
int utf_class(int c);
|
int utf_class(int c);
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ void cursor_on(void);
|
|||||||
void cursor_off(void);
|
void cursor_off(void);
|
||||||
void term_cursor_mode(int forced);
|
void term_cursor_mode(int forced);
|
||||||
void term_cursor_color(char_u *color);
|
void term_cursor_color(char_u *color);
|
||||||
void term_cursor_blink(int blink);
|
|
||||||
void term_cursor_shape(int shape, int blink);
|
void term_cursor_shape(int shape, int blink);
|
||||||
void scroll_region_set(win_T *wp, int off);
|
void scroll_region_set(win_T *wp, int off);
|
||||||
void scroll_region_reset(void);
|
void scroll_region_reset(void);
|
||||||
|
|||||||
@@ -9999,7 +9999,7 @@ highlight_changed(void)
|
|||||||
if (ga_grow(&highlight_ga, 28) == FAIL)
|
if (ga_grow(&highlight_ga, 28) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
hlcnt = highlight_ga.ga_len;
|
hlcnt = highlight_ga.ga_len;
|
||||||
if (id_S == 0)
|
if (id_S == -1)
|
||||||
{
|
{
|
||||||
/* Make sure id_S is always valid to simplify code below. Use the last
|
/* Make sure id_S is always valid to simplify code below. Use the last
|
||||||
* entry. */
|
* entry. */
|
||||||
|
|||||||
205
src/term.c
205
src/term.c
@@ -114,21 +114,22 @@ char *tgetstr(char *, char **);
|
|||||||
# else
|
# else
|
||||||
# define LOG_TR(msg)
|
# define LOG_TR(msg)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# define STATUS_GET 1 /* send request when switching to RAW mode */
|
||||||
|
# define STATUS_SENT 2 /* did send request, waiting for response */
|
||||||
|
# define STATUS_GOT 3 /* received response */
|
||||||
|
|
||||||
/* Request Terminal Version status: */
|
/* Request Terminal Version status: */
|
||||||
# define CRV_GET 1 /* send T_CRV when switched to RAW mode */
|
static int crv_status = STATUS_GET;
|
||||||
# define CRV_SENT 2 /* did send T_CRV, waiting for answer */
|
|
||||||
# define CRV_GOT 3 /* received T_CRV response */
|
|
||||||
static int crv_status = CRV_GET;
|
|
||||||
/* Request Cursor position report: */
|
/* Request Cursor position report: */
|
||||||
# define U7_GET 1 /* send T_U7 when switched to RAW mode */
|
static int u7_status = STATUS_GET;
|
||||||
# define U7_SENT 2 /* did send T_U7, waiting for answer */
|
|
||||||
# define U7_GOT 3 /* received T_U7 response */
|
|
||||||
static int u7_status = U7_GET;
|
|
||||||
/* Request background color report: */
|
/* Request background color report: */
|
||||||
# define RBG_GET 1 /* send T_RBG when switched to RAW mode */
|
static int rbg_status = STATUS_GET;
|
||||||
# define RBG_SENT 2 /* did send T_RBG, waiting for answer */
|
|
||||||
# define RBG_GOT 3 /* received T_RBG response */
|
/* Request cursor mode report: */
|
||||||
static int rbg_status = RBG_GET;
|
static int rcm_status = STATUS_GET;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -160,6 +161,14 @@ static char_u *vim_tgetstr(char *s, char_u **pp);
|
|||||||
|
|
||||||
static int detected_8bit = FALSE; /* detected 8-bit terminal */
|
static int detected_8bit = FALSE; /* detected 8-bit terminal */
|
||||||
|
|
||||||
|
#ifdef FEAT_TERMRESPONSE
|
||||||
|
/* When the cursor shape was detected these values are used:
|
||||||
|
* 1: block, 2: underline, 3: vertical bar
|
||||||
|
* initial_cursor_blink is only valid when initial_cursor_shape is not zero. */
|
||||||
|
static int initial_cursor_shape = 0;
|
||||||
|
static int initial_cursor_blink = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct builtin_term builtin_termcaps[] =
|
static struct builtin_term builtin_termcaps[] =
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -820,11 +829,13 @@ static struct builtin_term builtin_termcaps[] =
|
|||||||
{(int)KS_VI, IF_EB("\033[?25l", ESC_STR "[?25l")},
|
{(int)KS_VI, IF_EB("\033[?25l", ESC_STR "[?25l")},
|
||||||
{(int)KS_VE, IF_EB("\033[?25h", ESC_STR "[?25h")},
|
{(int)KS_VE, IF_EB("\033[?25h", ESC_STR "[?25h")},
|
||||||
{(int)KS_VS, IF_EB("\033[?12h", ESC_STR "[?12h")},
|
{(int)KS_VS, IF_EB("\033[?12h", ESC_STR "[?12h")},
|
||||||
|
{(int)KS_CVS, IF_EB("\033[?12l", ESC_STR "[?12l")},
|
||||||
# ifdef TERMINFO
|
# ifdef TERMINFO
|
||||||
{(int)KS_CSH, IF_EB("\033[%p1%d q", ESC_STR "[%p1%d q")},
|
{(int)KS_CSH, IF_EB("\033[%p1%d q", ESC_STR "[%p1%d q")},
|
||||||
# else
|
# else
|
||||||
{(int)KS_CSH, IF_EB("\033[%d q", ESC_STR "[%d q")},
|
{(int)KS_CSH, IF_EB("\033[%d q", ESC_STR "[%d q")},
|
||||||
# endif
|
# endif
|
||||||
|
{(int)KS_CRS, IF_EB("\033P$q q\033\\", ESC_STR "P$q q" ESC_STR "\\")},
|
||||||
# ifdef TERMINFO
|
# ifdef TERMINFO
|
||||||
{(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
|
{(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
|
||||||
ESC_STR "[%i%p1%d;%p2%dH")},
|
ESC_STR "[%i%p1%d;%p2%dH")},
|
||||||
@@ -1570,7 +1581,7 @@ set_termname(char_u *term)
|
|||||||
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
|
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
|
||||||
{KS_CL, "cl"}, {KS_CD, "cd"},
|
{KS_CL, "cl"}, {KS_CD, "cd"},
|
||||||
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
|
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
|
||||||
{KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
|
{KS_ME, "me"}, {KS_MR, "mr"},
|
||||||
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
|
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
|
||||||
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
|
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
|
||||||
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
|
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
|
||||||
@@ -1580,6 +1591,7 @@ set_termname(char_u *term)
|
|||||||
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
|
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
|
||||||
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
|
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
|
||||||
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
|
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
|
||||||
|
{KS_VS, "vs"}, {KS_CVS, "VS"},
|
||||||
{KS_CIS, "IS"}, {KS_CIE, "IE"},
|
{KS_CIS, "IS"}, {KS_CIE, "IE"},
|
||||||
{KS_CSC, "SC"}, {KS_CEC, "EC"},
|
{KS_CSC, "SC"}, {KS_CEC, "EC"},
|
||||||
{KS_TS, "ts"}, {KS_FS, "fs"},
|
{KS_TS, "ts"}, {KS_FS, "fs"},
|
||||||
@@ -1803,9 +1815,9 @@ set_termname(char_u *term)
|
|||||||
* is being used.
|
* is being used.
|
||||||
* Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
|
* Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
|
||||||
*/
|
*/
|
||||||
#ifdef FEAT_GUI
|
# ifdef FEAT_GUI
|
||||||
if (!gui.in_use)
|
if (!gui.in_use)
|
||||||
#endif
|
# endif
|
||||||
get_stty();
|
get_stty();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1906,8 +1918,8 @@ set_termname(char_u *term)
|
|||||||
full_screen = TRUE; /* we can use termcap codes from now on */
|
full_screen = TRUE; /* we can use termcap codes from now on */
|
||||||
set_term_defaults(); /* use current values as defaults */
|
set_term_defaults(); /* use current values as defaults */
|
||||||
#ifdef FEAT_TERMRESPONSE
|
#ifdef FEAT_TERMRESPONSE
|
||||||
LOG_TR("setting crv_status to CRV_GET");
|
LOG_TR("setting crv_status to STATUS_GET");
|
||||||
crv_status = CRV_GET; /* Get terminal version later */
|
crv_status = STATUS_GET; /* Get terminal version later */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3298,9 +3310,10 @@ settmode(int tmode)
|
|||||||
/* May need to check for T_CRV response and termcodes, it
|
/* May need to check for T_CRV response and termcodes, it
|
||||||
* doesn't work in Cooked mode, an external program may get
|
* doesn't work in Cooked mode, an external program may get
|
||||||
* them. */
|
* them. */
|
||||||
if (tmode != TMODE_RAW && (crv_status == CRV_SENT
|
if (tmode != TMODE_RAW && (crv_status == STATUS_SENT
|
||||||
|| u7_status == U7_SENT
|
|| u7_status == STATUS_SENT
|
||||||
|| rbg_status == RBG_SENT))
|
|| rbg_status == STATUS_SENT
|
||||||
|
|| rcm_status == STATUS_SENT))
|
||||||
(void)vpeekc_nomap();
|
(void)vpeekc_nomap();
|
||||||
check_for_codes_from_term();
|
check_for_codes_from_term();
|
||||||
}
|
}
|
||||||
@@ -3347,7 +3360,7 @@ starttermcap(void)
|
|||||||
may_req_termresponse();
|
may_req_termresponse();
|
||||||
/* Immediately check for a response. If t_Co changes, we don't
|
/* Immediately check for a response. If t_Co changes, we don't
|
||||||
* want to redraw with wrong colors first. */
|
* want to redraw with wrong colors first. */
|
||||||
if (crv_status == CRV_SENT)
|
if (crv_status == STATUS_SENT)
|
||||||
check_for_codes_from_term();
|
check_for_codes_from_term();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3367,8 +3380,10 @@ stoptermcap(void)
|
|||||||
# endif
|
# endif
|
||||||
{
|
{
|
||||||
/* May need to discard T_CRV, T_U7 or T_RBG response. */
|
/* May need to discard T_CRV, T_U7 or T_RBG response. */
|
||||||
if (crv_status == CRV_SENT || u7_status == U7_SENT
|
if (crv_status == STATUS_SENT
|
||||||
|| rbg_status == RBG_SENT)
|
|| u7_status == STATUS_SENT
|
||||||
|
|| rbg_status == STATUS_SENT
|
||||||
|
|| rcm_status == STATUS_SENT)
|
||||||
{
|
{
|
||||||
# ifdef UNIX
|
# ifdef UNIX
|
||||||
/* Give the terminal a chance to respond. */
|
/* Give the terminal a chance to respond. */
|
||||||
@@ -3414,14 +3429,14 @@ stoptermcap(void)
|
|||||||
void
|
void
|
||||||
may_req_termresponse(void)
|
may_req_termresponse(void)
|
||||||
{
|
{
|
||||||
if (crv_status == CRV_GET
|
if (crv_status == STATUS_GET
|
||||||
&& can_get_termresponse()
|
&& can_get_termresponse()
|
||||||
&& starting == 0
|
&& starting == 0
|
||||||
&& *T_CRV != NUL)
|
&& *T_CRV != NUL)
|
||||||
{
|
{
|
||||||
LOG_TR("Sending CRV");
|
LOG_TR("Sending CRV request");
|
||||||
out_str(T_CRV);
|
out_str(T_CRV);
|
||||||
crv_status = CRV_SENT;
|
crv_status = STATUS_SENT;
|
||||||
/* check for the characters now, otherwise they might be eaten by
|
/* check for the characters now, otherwise they might be eaten by
|
||||||
* get_keystroke() */
|
* get_keystroke() */
|
||||||
out_flush();
|
out_flush();
|
||||||
@@ -3442,7 +3457,7 @@ may_req_termresponse(void)
|
|||||||
void
|
void
|
||||||
may_req_ambiguous_char_width(void)
|
may_req_ambiguous_char_width(void)
|
||||||
{
|
{
|
||||||
if (u7_status == U7_GET
|
if (u7_status == STATUS_GET
|
||||||
&& can_get_termresponse()
|
&& can_get_termresponse()
|
||||||
&& starting == 0
|
&& starting == 0
|
||||||
&& *T_U7 != NUL
|
&& *T_U7 != NUL
|
||||||
@@ -3457,7 +3472,7 @@ may_req_ambiguous_char_width(void)
|
|||||||
buf[mb_char2bytes(0x25bd, buf)] = 0;
|
buf[mb_char2bytes(0x25bd, buf)] = 0;
|
||||||
out_str(buf);
|
out_str(buf);
|
||||||
out_str(T_U7);
|
out_str(T_U7);
|
||||||
u7_status = U7_SENT;
|
u7_status = STATUS_SENT;
|
||||||
out_flush();
|
out_flush();
|
||||||
|
|
||||||
/* This overwrites a few characters on the screen, a redraw is needed
|
/* This overwrites a few characters on the screen, a redraw is needed
|
||||||
@@ -3477,19 +3492,40 @@ may_req_ambiguous_char_width(void)
|
|||||||
/*
|
/*
|
||||||
* Similar to requesting the version string: Request the terminal background
|
* Similar to requesting the version string: Request the terminal background
|
||||||
* color when it is the right moment.
|
* color when it is the right moment.
|
||||||
|
* Also request the cursor shape, if possible.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
may_req_bg_color(void)
|
may_req_bg_color(void)
|
||||||
{
|
{
|
||||||
if (rbg_status == RBG_GET
|
int done = FALSE;
|
||||||
&& can_get_termresponse()
|
|
||||||
&& starting == 0
|
if (can_get_termresponse() && starting == 0)
|
||||||
|
{
|
||||||
|
/* Only request background if t_RB is set and 'background' wasn't
|
||||||
|
* changed. */
|
||||||
|
if (rbg_status == STATUS_GET
|
||||||
&& *T_RBG != NUL
|
&& *T_RBG != NUL
|
||||||
&& !option_was_set((char_u *)"bg"))
|
&& !option_was_set((char_u *)"bg"))
|
||||||
{
|
{
|
||||||
LOG_TR("Sending BG request");
|
LOG_TR("Sending BG request");
|
||||||
out_str(T_RBG);
|
out_str(T_RBG);
|
||||||
rbg_status = RBG_SENT;
|
rbg_status = STATUS_SENT;
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only request the cursor shape if t_SH and t_RS are set. */
|
||||||
|
if (rcm_status == STATUS_GET
|
||||||
|
&& *T_CSH != NUL
|
||||||
|
&& *T_CRS != NUL)
|
||||||
|
{
|
||||||
|
LOG_TR("Sending cursor shape request");
|
||||||
|
out_str(T_CRS);
|
||||||
|
rcm_status = STATUS_SENT;
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
{
|
||||||
/* check for the characters now, otherwise they might be eaten by
|
/* check for the characters now, otherwise they might be eaten by
|
||||||
* get_keystroke() */
|
* get_keystroke() */
|
||||||
out_flush();
|
out_flush();
|
||||||
@@ -3626,10 +3662,10 @@ mouse_model_popup(void)
|
|||||||
void
|
void
|
||||||
scroll_start(void)
|
scroll_start(void)
|
||||||
{
|
{
|
||||||
if (*T_VS != NUL)
|
if (*T_VS != NUL && *T_CVS != NUL)
|
||||||
{
|
{
|
||||||
out_str(T_VS);
|
out_str(T_VS);
|
||||||
out_str(T_VE);
|
out_str(T_CVS);
|
||||||
screen_start(); /* don't know where cursor is now */
|
screen_start(); /* don't know where cursor is now */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3655,9 +3691,8 @@ cursor_on(void)
|
|||||||
void
|
void
|
||||||
cursor_off(void)
|
cursor_off(void)
|
||||||
{
|
{
|
||||||
if (full_screen)
|
if (full_screen && !cursor_is_off)
|
||||||
{
|
{
|
||||||
if (!cursor_is_off)
|
|
||||||
out_str(T_VI); /* disable cursor */
|
out_str(T_VI); /* disable cursor */
|
||||||
cursor_is_off = TRUE;
|
cursor_is_off = TRUE;
|
||||||
}
|
}
|
||||||
@@ -3676,7 +3711,14 @@ term_cursor_mode(int forced)
|
|||||||
/* Only do something when redrawing the screen and we can restore the
|
/* Only do something when redrawing the screen and we can restore the
|
||||||
* mode. */
|
* mode. */
|
||||||
if (!full_screen || *T_CEI == NUL)
|
if (!full_screen || *T_CEI == NUL)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_TERMRESPONSE
|
||||||
|
if (forced && initial_cursor_shape > 0)
|
||||||
|
/* Restore to initial values. */
|
||||||
|
term_cursor_shape(initial_cursor_shape, initial_cursor_blink);
|
||||||
|
# endif
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((State & REPLACE) == REPLACE)
|
if ((State & REPLACE) == REPLACE)
|
||||||
{
|
{
|
||||||
@@ -3720,19 +3762,10 @@ term_cursor_color(char_u *color)
|
|||||||
out_flush();
|
out_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
void
|
|
||||||
term_cursor_blink(int blink)
|
|
||||||
{
|
|
||||||
if (blink)
|
|
||||||
out_str(T_VS);
|
|
||||||
else
|
|
||||||
out_str(T_VE);
|
|
||||||
out_flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "shape" == 1: block, "shape" == 2: underline, "shape" == 3: vertical bar
|
* "shape": 1 = block, 2 = underline, 3 = vertical bar
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
term_cursor_shape(int shape, int blink)
|
term_cursor_shape(int shape, int blink)
|
||||||
@@ -3742,8 +3775,18 @@ term_cursor_shape(int shape, int blink)
|
|||||||
OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink));
|
OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink));
|
||||||
out_flush();
|
out_flush();
|
||||||
}
|
}
|
||||||
|
/* When t_SH is not set try setting just the blink state. */
|
||||||
|
else if (blink && *T_VS != NUL)
|
||||||
|
{
|
||||||
|
out_str(T_VS);
|
||||||
|
out_flush();
|
||||||
|
}
|
||||||
|
else if (!blink && *T_CVS != NUL)
|
||||||
|
{
|
||||||
|
out_str(T_CVS);
|
||||||
|
out_flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4290,7 +4333,8 @@ check_termcode(
|
|||||||
{
|
{
|
||||||
/* Skip over the digits, the final char must
|
/* Skip over the digits, the final char must
|
||||||
* follow. */
|
* follow. */
|
||||||
for (j = slen - 2; j < len && (isdigit(tp[j]) || tp[j] == ';'); ++j)
|
for (j = slen - 2; j < len && (isdigit(tp[j])
|
||||||
|
|| tp[j] == ';'); ++j)
|
||||||
;
|
;
|
||||||
++j;
|
++j;
|
||||||
if (len < j) /* got a partial sequence */
|
if (len < j) /* got a partial sequence */
|
||||||
@@ -4394,7 +4438,7 @@ check_termcode(
|
|||||||
char *aw = NULL;
|
char *aw = NULL;
|
||||||
|
|
||||||
LOG_TR("Received U7 status");
|
LOG_TR("Received U7 status");
|
||||||
u7_status = U7_GOT;
|
u7_status = STATUS_GOT;
|
||||||
# ifdef FEAT_AUTOCMD
|
# ifdef FEAT_AUTOCMD
|
||||||
did_cursorhold = TRUE;
|
did_cursorhold = TRUE;
|
||||||
# endif
|
# endif
|
||||||
@@ -4433,8 +4477,8 @@ check_termcode(
|
|||||||
/* eat it when at least one digit and ending in 'c' */
|
/* eat it when at least one digit and ending in 'c' */
|
||||||
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
|
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
|
||||||
{
|
{
|
||||||
LOG_TR("Received CRV");
|
LOG_TR("Received CRV response");
|
||||||
crv_status = CRV_GOT;
|
crv_status = STATUS_GOT;
|
||||||
# ifdef FEAT_AUTOCMD
|
# ifdef FEAT_AUTOCMD
|
||||||
did_cursorhold = TRUE;
|
did_cursorhold = TRUE;
|
||||||
# endif
|
# endif
|
||||||
@@ -4566,8 +4610,8 @@ check_termcode(
|
|||||||
char *newval = (3 * '6' < tp[j+7] + tp[j+12]
|
char *newval = (3 * '6' < tp[j+7] + tp[j+12]
|
||||||
+ tp[j+17]) ? "light" : "dark";
|
+ tp[j+17]) ? "light" : "dark";
|
||||||
|
|
||||||
LOG_TR("Received RBG");
|
LOG_TR("Received RBG response");
|
||||||
rbg_status = RBG_GOT;
|
rbg_status = STATUS_GOT;
|
||||||
if (STRCMP(p_bg, newval) != 0)
|
if (STRCMP(p_bg, newval) != 0)
|
||||||
{
|
{
|
||||||
/* value differs, apply it */
|
/* value differs, apply it */
|
||||||
@@ -4582,6 +4626,10 @@ check_termcode(
|
|||||||
key_name[0] = (int)KS_EXTRA;
|
key_name[0] = (int)KS_EXTRA;
|
||||||
key_name[1] = (int)KE_IGNORE;
|
key_name[1] = (int)KE_IGNORE;
|
||||||
slen = i + 1 + (tp[i] == ESC);
|
slen = i + 1 + (tp[i] == ESC);
|
||||||
|
if (tp[i] == 0x07 && i + 1 < len && tp[i + 1] == 0x18)
|
||||||
|
/* Sometimes the 0x07 is followed by 0x18, unclear
|
||||||
|
* when this happens. */
|
||||||
|
++slen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == len)
|
if (i == len)
|
||||||
@@ -4592,24 +4640,33 @@ check_termcode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for key code response from xterm:
|
/* Check for key code response from xterm:
|
||||||
*
|
|
||||||
* {lead}{flag}+r<hex bytes><{tail}
|
* {lead}{flag}+r<hex bytes><{tail}
|
||||||
*
|
*
|
||||||
* {lead} can be <Esc>P or DCS
|
* {lead} can be <Esc>P or DCS
|
||||||
* {flag} can be '0' or '1'
|
* {flag} can be '0' or '1'
|
||||||
* {tail} can be Esc>\ or STERM
|
* {tail} can be Esc>\ or STERM
|
||||||
*
|
*
|
||||||
* Consume any code that starts with "{lead}.+r".
|
* Check for cursor shape response from xterm:
|
||||||
|
* {lead}1$r<number> q{tail}
|
||||||
|
*
|
||||||
|
* {lead} can be <Esc>P or DCS
|
||||||
|
* {tail} can be Esc>\ or STERM
|
||||||
|
*
|
||||||
|
* Consume any code that starts with "{lead}.+r" or "{lead}.$r".
|
||||||
*/
|
*/
|
||||||
else if (check_for_codes
|
else if ((check_for_codes || rcm_status == STATUS_SENT)
|
||||||
&& ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
|
&& ((tp[0] == ESC && len >= 2 && tp[1] == 'P')
|
||||||
|| tp[0] == DCS))
|
|| tp[0] == DCS))
|
||||||
{
|
{
|
||||||
j = 1 + (tp[0] == ESC);
|
j = 1 + (tp[0] == ESC);
|
||||||
if (len >= j + 3 && (argp[1] != '+' || argp[2] != 'r'))
|
if (len < j + 3)
|
||||||
|
i = len; /* need more chars */
|
||||||
|
else if ((argp[1] != '+' && argp[1] != '$') || argp[2] != 'r')
|
||||||
i = 0; /* no match */
|
i = 0; /* no match */
|
||||||
else
|
else if (argp[1] == '+')
|
||||||
|
/* key code response */
|
||||||
for (i = j; i < len; ++i)
|
for (i = j; i < len; ++i)
|
||||||
|
{
|
||||||
if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
|
if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
|
||||||
|| tp[i] == STERM)
|
|| tp[i] == STERM)
|
||||||
{
|
{
|
||||||
@@ -4620,6 +4677,34 @@ check_termcode(
|
|||||||
slen = i + 1 + (tp[i] == ESC);
|
slen = i + 1 + (tp[i] == ESC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if ((len >= j + 6 && isdigit(argp[3]))
|
||||||
|
&& argp[4] == ' '
|
||||||
|
&& argp[5] == 'q')
|
||||||
|
{
|
||||||
|
/* cursor shape response */
|
||||||
|
i = j + 6;
|
||||||
|
if ((tp[i] == ESC && i + 1 < len && tp[i + 1] == '\\')
|
||||||
|
|| tp[i] == STERM)
|
||||||
|
{
|
||||||
|
int number = argp[3] - '0';
|
||||||
|
|
||||||
|
/* 0, 1 = block blink, 2 = block
|
||||||
|
* 3 = underline blink, 4 = underline
|
||||||
|
* 5 = vertical bar blink, 6 = vertical bar */
|
||||||
|
number = number == 0 ? 1 : number;
|
||||||
|
initial_cursor_shape = (number + 1) / 2;
|
||||||
|
/* The blink flag is actually inverted, compared to
|
||||||
|
* the value set with T_SH. */
|
||||||
|
initial_cursor_blink = (number & 1) ? FALSE : TRUE;
|
||||||
|
rcm_status = STATUS_GOT;
|
||||||
|
LOG_TR("Received cursor shape response");
|
||||||
|
|
||||||
|
key_name[0] = (int)KS_EXTRA;
|
||||||
|
key_name[1] = (int)KE_IGNORE;
|
||||||
|
slen = i + 1 + (tp[i] == ESC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (i == len)
|
if (i == len)
|
||||||
{
|
{
|
||||||
@@ -5837,7 +5922,7 @@ gather_termleader(void)
|
|||||||
termleader[len++] = CSI; /* the GUI codes are not in termcodes[] */
|
termleader[len++] = CSI; /* the GUI codes are not in termcodes[] */
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_TERMRESPONSE
|
#ifdef FEAT_TERMRESPONSE
|
||||||
if (check_for_codes)
|
if (check_for_codes || *T_CRS != NUL)
|
||||||
termleader[len++] = DCS; /* the termcode response starts with DCS
|
termleader[len++] = DCS; /* the termcode response starts with DCS
|
||||||
in 8-bit mode */
|
in 8-bit mode */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ enum SpecialKey
|
|||||||
KS_DB, /* text may be scrolled up from down */
|
KS_DB, /* text may be scrolled up from down */
|
||||||
KS_VI, /* cursor invisible */
|
KS_VI, /* cursor invisible */
|
||||||
KS_VE, /* cursor visible */
|
KS_VE, /* cursor visible */
|
||||||
KS_VS, /* cursor very visible */
|
KS_VS, /* cursor very visible (blink) */
|
||||||
|
KS_CVS, /* cursor normally visible (no blink) */
|
||||||
KS_CSH, /* cursor shape */
|
KS_CSH, /* cursor shape */
|
||||||
|
KS_CRS, /* request cursor shape */
|
||||||
KS_ME, /* normal mode */
|
KS_ME, /* normal mode */
|
||||||
KS_MR, /* reverse mode */
|
KS_MR, /* reverse mode */
|
||||||
KS_MD, /* bold mode */
|
KS_MD, /* bold mode */
|
||||||
@@ -130,8 +132,10 @@ extern char_u *(term_strings[]); /* current terminal strings */
|
|||||||
#define T_DB (TERM_STR(KS_DB)) /* text may be scrolled up from down */
|
#define T_DB (TERM_STR(KS_DB)) /* text may be scrolled up from down */
|
||||||
#define T_VI (TERM_STR(KS_VI)) /* cursor invisible */
|
#define T_VI (TERM_STR(KS_VI)) /* cursor invisible */
|
||||||
#define T_VE (TERM_STR(KS_VE)) /* cursor visible */
|
#define T_VE (TERM_STR(KS_VE)) /* cursor visible */
|
||||||
#define T_VS (TERM_STR(KS_VS)) /* cursor very visible */
|
#define T_VS (TERM_STR(KS_VS)) /* cursor very visible (blink) */
|
||||||
|
#define T_CVS (TERM_STR(KS_CVS)) /* cursor normally visible (no blink) */
|
||||||
#define T_CSH (TERM_STR(KS_CSH)) /* cursor shape */
|
#define T_CSH (TERM_STR(KS_CSH)) /* cursor shape */
|
||||||
|
#define T_CRS (TERM_STR(KS_CRS)) /* request cursor shape */
|
||||||
#define T_ME (TERM_STR(KS_ME)) /* normal mode */
|
#define T_ME (TERM_STR(KS_ME)) /* normal mode */
|
||||||
#define T_MR (TERM_STR(KS_MR)) /* reverse mode */
|
#define T_MR (TERM_STR(KS_MR)) /* reverse mode */
|
||||||
#define T_MD (TERM_STR(KS_MD)) /* bold mode */
|
#define T_MD (TERM_STR(KS_MD)) /* bold mode */
|
||||||
|
|||||||
261
src/terminal.c
261
src/terminal.c
@@ -38,11 +38,20 @@
|
|||||||
* in tl_scrollback are no longer used.
|
* in tl_scrollback are no longer used.
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - make [range]terminal pipe [range] lines to the terminal
|
* - better check for blinking - reply from Thomas Dickey Aug 22
|
||||||
|
* - test for writing lines to terminal job does not work on MS-Windows
|
||||||
* - implement term_setsize()
|
* - implement term_setsize()
|
||||||
* - add test for giving error for invalid 'termsize' value.
|
* - add test for giving error for invalid 'termsize' value.
|
||||||
* - support minimal size when 'termsize' is "rows*cols".
|
* - support minimal size when 'termsize' is "rows*cols".
|
||||||
* - support minimal size when 'termsize' is empty?
|
* - support minimal size when 'termsize' is empty?
|
||||||
|
* - do not set bufhidden to "hide"? works like a buffer with changes.
|
||||||
|
* document that CTRL-W :hide can be used.
|
||||||
|
* - GUI: when using tabs, focus in terminal, click on tab does not work.
|
||||||
|
* - GUI: when 'confirm' is set and trying to exit Vim, dialog offers to save
|
||||||
|
* changes to "!shell".
|
||||||
|
* (justrajdeep, 2017 Aug 22)
|
||||||
|
* - command argument with spaces doesn't work #1999
|
||||||
|
* :terminal ls dir\ with\ spaces
|
||||||
* - implement job options when starting a terminal. Allow:
|
* - implement job options when starting a terminal. Allow:
|
||||||
* "in_io", "in_top", "in_bot", "in_name", "in_buf"
|
* "in_io", "in_top", "in_bot", "in_name", "in_buf"
|
||||||
"out_io", "out_name", "out_buf", "out_modifiable", "out_msg"
|
"out_io", "out_name", "out_buf", "out_modifiable", "out_msg"
|
||||||
@@ -59,7 +68,6 @@
|
|||||||
* mouse in the Terminal window for copy/paste.
|
* mouse in the Terminal window for copy/paste.
|
||||||
* - when 'encoding' is not utf-8, or the job is using another encoding, setup
|
* - when 'encoding' is not utf-8, or the job is using another encoding, setup
|
||||||
* conversions.
|
* conversions.
|
||||||
* - update ":help function-list" for terminal functions.
|
|
||||||
* - In the GUI use a terminal emulator for :!cmd.
|
* - In the GUI use a terminal emulator for :!cmd.
|
||||||
* - Copy text in the vterm to the Vim buffer once in a while, so that
|
* - Copy text in the vterm to the Vim buffer once in a while, so that
|
||||||
* completion works.
|
* completion works.
|
||||||
@@ -447,10 +455,14 @@ ex_terminal(exarg_T *eap)
|
|||||||
cmd = eap->arg;
|
cmd = eap->arg;
|
||||||
while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
|
while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p, *ep;
|
||||||
|
|
||||||
cmd += 2;
|
cmd += 2;
|
||||||
p = skiptowhite(cmd);
|
p = skiptowhite(cmd);
|
||||||
|
ep = vim_strchr(cmd, '=');
|
||||||
|
if (ep != NULL && ep < p)
|
||||||
|
p = ep;
|
||||||
|
|
||||||
if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0)
|
if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0)
|
||||||
opt.jo_term_finish = 'c';
|
opt.jo_term_finish = 'c';
|
||||||
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
|
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
|
||||||
@@ -459,6 +471,20 @@ ex_terminal(exarg_T *eap)
|
|||||||
opt.jo_curwin = 1;
|
opt.jo_curwin = 1;
|
||||||
else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0)
|
else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0)
|
||||||
opt.jo_hidden = 1;
|
opt.jo_hidden = 1;
|
||||||
|
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "rows", 4) == 0
|
||||||
|
&& ep != NULL && isdigit(ep[1]))
|
||||||
|
{
|
||||||
|
opt.jo_set2 |= JO2_TERM_ROWS;
|
||||||
|
opt.jo_term_rows = atoi((char *)ep + 1);
|
||||||
|
p = skiptowhite(cmd);
|
||||||
|
}
|
||||||
|
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "cols", 4) == 0
|
||||||
|
&& ep != NULL && isdigit(ep[1]))
|
||||||
|
{
|
||||||
|
opt.jo_set2 |= JO2_TERM_COLS;
|
||||||
|
opt.jo_term_cols = atoi((char *)ep + 1);
|
||||||
|
p = skiptowhite(cmd);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*p)
|
if (*p)
|
||||||
@@ -472,17 +498,14 @@ ex_terminal(exarg_T *eap)
|
|||||||
/* Make a copy, an autocommand may set 'shell'. */
|
/* Make a copy, an autocommand may set 'shell'. */
|
||||||
tofree = cmd = vim_strsave(p_sh);
|
tofree = cmd = vim_strsave(p_sh);
|
||||||
|
|
||||||
if (eap->addr_count == 2)
|
if (eap->addr_count > 0)
|
||||||
{
|
{
|
||||||
opt.jo_term_rows = eap->line1;
|
/* Write lines from current buffer to the job. */
|
||||||
opt.jo_term_cols = eap->line2;
|
opt.jo_set |= JO_IN_IO | JO_IN_BUF | JO_IN_TOP | JO_IN_BOT;
|
||||||
}
|
opt.jo_io[PART_IN] = JIO_BUFFER;
|
||||||
else if (eap->addr_count == 1)
|
opt.jo_io_buf[PART_IN] = curbuf->b_fnum;
|
||||||
{
|
opt.jo_in_top = eap->line1;
|
||||||
if (cmdmod.split & WSP_VERT)
|
opt.jo_in_bot = eap->line2;
|
||||||
opt.jo_term_cols = eap->line2;
|
|
||||||
else
|
|
||||||
opt.jo_term_rows = eap->line2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
argvar.v_type = VAR_STRING;
|
argvar.v_type = VAR_STRING;
|
||||||
@@ -830,6 +853,25 @@ add_scrollback_line_to_buffer(term_T *term, char_u *text, int len)
|
|||||||
int empty = (buf->b_ml.ml_flags & ML_EMPTY);
|
int empty = (buf->b_ml.ml_flags & ML_EMPTY);
|
||||||
linenr_T lnum = buf->b_ml.ml_line_count;
|
linenr_T lnum = buf->b_ml.ml_line_count;
|
||||||
|
|
||||||
|
#ifdef WIN3264
|
||||||
|
if (!enc_utf8 && enc_codepage > 0)
|
||||||
|
{
|
||||||
|
WCHAR *ret = NULL;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
MultiByteToWideChar_alloc(CP_UTF8, 0, (char*)text, len + 1,
|
||||||
|
&ret, &length);
|
||||||
|
if (ret != NULL)
|
||||||
|
{
|
||||||
|
WideCharToMultiByte_alloc(enc_codepage, 0,
|
||||||
|
ret, length, (char **)&text, &len, 0, 0);
|
||||||
|
vim_free(ret);
|
||||||
|
ml_append_buf(term->tl_buffer, lnum, text, len, FALSE);
|
||||||
|
vim_free(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE);
|
ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE);
|
||||||
if (empty)
|
if (empty)
|
||||||
{
|
{
|
||||||
@@ -903,7 +945,7 @@ move_terminal_to_buffer(term_T *term)
|
|||||||
width = 1;
|
width = 1;
|
||||||
vim_memset(p + pos.col, 0, sizeof(cellattr_T));
|
vim_memset(p + pos.col, 0, sizeof(cellattr_T));
|
||||||
if (ga_grow(&ga, 1) == OK)
|
if (ga_grow(&ga, 1) == OK)
|
||||||
ga.ga_len += mb_char2bytes(' ',
|
ga.ga_len += utf_char2bytes(' ',
|
||||||
(char_u *)ga.ga_data + ga.ga_len);
|
(char_u *)ga.ga_data + ga.ga_len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -921,7 +963,7 @@ move_terminal_to_buffer(term_T *term)
|
|||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i)
|
for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i)
|
||||||
ga.ga_len += mb_char2bytes(c == NUL ? ' ' : c,
|
ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c,
|
||||||
(char_u *)ga.ga_data + ga.ga_len);
|
(char_u *)ga.ga_data + ga.ga_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1036,14 +1078,13 @@ term_enter_job_mode()
|
|||||||
|
|
||||||
/* Remove the terminal contents from the scrollback and the buffer. */
|
/* Remove the terminal contents from the scrollback and the buffer. */
|
||||||
gap = &term->tl_scrollback;
|
gap = &term->tl_scrollback;
|
||||||
while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled)
|
while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
|
||||||
|
&& gap->ga_len > 0)
|
||||||
{
|
{
|
||||||
ml_delete(curbuf->b_ml.ml_line_count, FALSE);
|
ml_delete(curbuf->b_ml.ml_line_count, FALSE);
|
||||||
line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
|
line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
|
||||||
vim_free(line->sb_cells);
|
vim_free(line->sb_cells);
|
||||||
--gap->ga_len;
|
--gap->ga_len;
|
||||||
if (gap->ga_len == 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
check_cursor();
|
check_cursor();
|
||||||
|
|
||||||
@@ -1078,6 +1119,29 @@ term_vgetc()
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the part that is connected to the tty. Normally this is PART_IN, but
|
||||||
|
* when writing buffer lines to the job it can be another. This makes it
|
||||||
|
* possible to do "1,5term vim -".
|
||||||
|
*/
|
||||||
|
static ch_part_T
|
||||||
|
get_tty_part(term_T *term)
|
||||||
|
{
|
||||||
|
#ifdef UNIX
|
||||||
|
ch_part_T parts[3] = {PART_IN, PART_OUT, PART_ERR};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
int fd = term->tl_job->jv_channel->ch_part[parts[i]].ch_fd;
|
||||||
|
|
||||||
|
if (isatty(fd))
|
||||||
|
return parts[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return PART_IN;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send keys to terminal.
|
* Send keys to terminal.
|
||||||
* Return FAIL when the key needs to be handled in Normal mode.
|
* Return FAIL when the key needs to be handled in Normal mode.
|
||||||
@@ -1149,7 +1213,7 @@ send_keys_to_term(term_T *term, int c, int typed)
|
|||||||
len = term_convert_key(term, c, msg);
|
len = term_convert_key(term, c, msg);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
/* TODO: if FAIL is returned, stop? */
|
/* TODO: if FAIL is returned, stop? */
|
||||||
channel_send(term->tl_job->jv_channel, PART_IN,
|
channel_send(term->tl_job->jv_channel, get_tty_part(term),
|
||||||
(char_u *)msg, (int)len, NULL);
|
(char_u *)msg, (int)len, NULL);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -1202,9 +1266,31 @@ term_paste_register(int prev_c UNUSED)
|
|||||||
for (item = l->lv_first; item != NULL; item = item->li_next)
|
for (item = l->lv_first; item != NULL; item = item->li_next)
|
||||||
{
|
{
|
||||||
char_u *s = get_tv_string(&item->li_tv);
|
char_u *s = get_tv_string(&item->li_tv);
|
||||||
|
#ifdef WIN3264
|
||||||
|
char_u *tmp = s;
|
||||||
|
|
||||||
|
if (!enc_utf8 && enc_codepage > 0)
|
||||||
|
{
|
||||||
|
WCHAR *ret = NULL;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
MultiByteToWideChar_alloc(enc_codepage, 0, (char*)s, STRLEN(s),
|
||||||
|
&ret, &length);
|
||||||
|
if (ret != NULL)
|
||||||
|
{
|
||||||
|
WideCharToMultiByte_alloc(CP_UTF8, 0,
|
||||||
|
ret, length, (char **)&s, &length, 0, 0);
|
||||||
|
vim_free(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN,
|
channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN,
|
||||||
s, STRLEN(s), NULL);
|
s, STRLEN(s), NULL);
|
||||||
|
#ifdef WIN3264
|
||||||
|
if (tmp != s)
|
||||||
|
vim_free(s);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (item->li_next != NULL || type == MLINE)
|
if (item->li_next != NULL || type == MLINE)
|
||||||
channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN,
|
channel_send(curbuf->b_term->tl_job->jv_channel, PART_IN,
|
||||||
(char_u *)"\r", 1, NULL);
|
(char_u *)"\r", 1, NULL);
|
||||||
@@ -1239,7 +1325,7 @@ term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg)
|
|||||||
{
|
{
|
||||||
entry.blinkwait = 700;
|
entry.blinkwait = 700;
|
||||||
entry.blinkon = 400;
|
entry.blinkon = 400;
|
||||||
entry.blinkon = 250;
|
entry.blinkoff = 250;
|
||||||
}
|
}
|
||||||
*fg = gui.back_pixel;
|
*fg = gui.back_pixel;
|
||||||
if (term->tl_cursor_color == NULL)
|
if (term->tl_cursor_color == NULL)
|
||||||
@@ -1271,8 +1357,6 @@ may_set_cursor_props(term_T *term)
|
|||||||
term_cursor_color(term->tl_cursor_color);
|
term_cursor_color(term->tl_cursor_color);
|
||||||
else
|
else
|
||||||
term_cursor_color((char_u *)"");
|
term_cursor_color((char_u *)"");
|
||||||
/* do both blink and shape+blink, in case setting shape does not work */
|
|
||||||
term_cursor_blink(term->tl_cursor_blink);
|
|
||||||
term_cursor_shape(term->tl_cursor_shape, term->tl_cursor_blink);
|
term_cursor_shape(term->tl_cursor_shape, term->tl_cursor_blink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1287,9 +1371,9 @@ may_restore_cursor_props(void)
|
|||||||
if (did_change_cursor)
|
if (did_change_cursor)
|
||||||
{
|
{
|
||||||
did_change_cursor = FALSE;
|
did_change_cursor = FALSE;
|
||||||
ui_cursor_shape_forced(TRUE);
|
|
||||||
term_cursor_color((char_u *)"");
|
term_cursor_color((char_u *)"");
|
||||||
term_cursor_blink(FALSE);
|
/* this will restore the initial cursor style, if possible */
|
||||||
|
ui_cursor_shape_forced(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1335,7 +1419,8 @@ terminal_loop(void)
|
|||||||
|
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
{
|
{
|
||||||
int fd = curbuf->b_term->tl_job->jv_channel->ch_part[PART_IN].ch_fd;
|
int part = get_tty_part(curbuf->b_term);
|
||||||
|
int fd = curbuf->b_term->tl_job->jv_channel->ch_part[part].ch_fd;
|
||||||
|
|
||||||
if (isatty(fd))
|
if (isatty(fd))
|
||||||
{
|
{
|
||||||
@@ -1432,6 +1517,18 @@ terminal_loop(void)
|
|||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# ifdef WIN3264
|
||||||
|
if (!enc_utf8 && has_mbyte && c >= 0x80)
|
||||||
|
{
|
||||||
|
WCHAR wc;
|
||||||
|
char_u mb[3];
|
||||||
|
|
||||||
|
mb[0] = (unsigned)c >> 8;
|
||||||
|
mb[1] = c;
|
||||||
|
if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
|
||||||
|
c = wc;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
|
if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
|
||||||
{
|
{
|
||||||
ret = OK;
|
ret = OK;
|
||||||
@@ -1740,6 +1837,24 @@ handle_settermprop(
|
|||||||
* displayed */
|
* displayed */
|
||||||
if (*skipwhite((char_u *)value->string) == NUL)
|
if (*skipwhite((char_u *)value->string) == NUL)
|
||||||
term->tl_title = NULL;
|
term->tl_title = NULL;
|
||||||
|
#ifdef WIN3264
|
||||||
|
else if (!enc_utf8 && enc_codepage > 0)
|
||||||
|
{
|
||||||
|
WCHAR *ret = NULL;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
MultiByteToWideChar_alloc(CP_UTF8, 0,
|
||||||
|
(char*)value->string, STRLEN(value->string),
|
||||||
|
&ret, &length);
|
||||||
|
if (ret != NULL)
|
||||||
|
{
|
||||||
|
WideCharToMultiByte_alloc(enc_codepage, 0,
|
||||||
|
ret, length, (char**)&term->tl_title,
|
||||||
|
&length, 0, 0);
|
||||||
|
vim_free(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
term->tl_title = vim_strsave((char_u *)value->string);
|
term->tl_title = vim_strsave((char_u *)value->string);
|
||||||
vim_free(term->tl_status_text);
|
vim_free(term->tl_status_text);
|
||||||
@@ -1846,7 +1961,7 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; (c = cells[col].chars[i]) > 0 || i == 0; ++i)
|
for (i = 0; (c = cells[col].chars[i]) > 0 || i == 0; ++i)
|
||||||
ga.ga_len += mb_char2bytes(c == NUL ? ' ' : c,
|
ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c,
|
||||||
(char_u *)ga.ga_data + ga.ga_len);
|
(char_u *)ga.ga_data + ga.ga_len);
|
||||||
p[col].width = cells[col].width;
|
p[col].width = cells[col].width;
|
||||||
p[col].attrs = cells[col].attrs;
|
p[col].attrs = cells[col].attrs;
|
||||||
@@ -2032,15 +2147,14 @@ term_update_window(win_T *wp)
|
|||||||
if (c == NUL)
|
if (c == NUL)
|
||||||
{
|
{
|
||||||
ScreenLines[off] = ' ';
|
ScreenLines[off] = ' ';
|
||||||
#if defined(FEAT_MBYTE)
|
|
||||||
if (enc_utf8)
|
if (enc_utf8)
|
||||||
ScreenLinesUC[off] = NUL;
|
ScreenLinesUC[off] = NUL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(FEAT_MBYTE)
|
if (enc_utf8)
|
||||||
if (enc_utf8 && c >= 0x80)
|
{
|
||||||
|
if (c >= 0x80)
|
||||||
{
|
{
|
||||||
ScreenLines[off] = ' ';
|
ScreenLines[off] = ' ';
|
||||||
ScreenLinesUC[off] = c;
|
ScreenLinesUC[off] = c;
|
||||||
@@ -2048,12 +2162,28 @@ term_update_window(win_T *wp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScreenLines[off] = c;
|
ScreenLines[off] = c;
|
||||||
if (enc_utf8)
|
|
||||||
ScreenLinesUC[off] = NUL;
|
ScreenLinesUC[off] = NUL;
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
|
#ifdef WIN3264
|
||||||
|
else if (has_mbyte && c >= 0x80)
|
||||||
|
{
|
||||||
|
char_u mb[MB_MAXBYTES+1];
|
||||||
|
WCHAR wc = c;
|
||||||
|
|
||||||
|
if (WideCharToMultiByte(GetACP(), 0, &wc, 1,
|
||||||
|
(char*)mb, 2, 0, 0) > 1)
|
||||||
|
{
|
||||||
|
ScreenLines[off] = mb[0];
|
||||||
|
ScreenLines[off + 1] = mb[1];
|
||||||
|
cell.width = mb_ptr2cells(mb);
|
||||||
|
}
|
||||||
|
else
|
||||||
ScreenLines[off] = c;
|
ScreenLines[off] = c;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else
|
||||||
|
ScreenLines[off] = c;
|
||||||
}
|
}
|
||||||
ScreenAttrs[off] = cell2attr(cell.attrs, cell.fg, cell.bg);
|
ScreenAttrs[off] = cell2attr(cell.attrs, cell.fg, cell.bg);
|
||||||
|
|
||||||
@@ -2061,11 +2191,14 @@ term_update_window(win_T *wp)
|
|||||||
++off;
|
++off;
|
||||||
if (cell.width == 2)
|
if (cell.width == 2)
|
||||||
{
|
{
|
||||||
ScreenLines[off] = NUL;
|
|
||||||
#if defined(FEAT_MBYTE)
|
|
||||||
if (enc_utf8)
|
if (enc_utf8)
|
||||||
ScreenLinesUC[off] = NUL;
|
ScreenLinesUC[off] = NUL;
|
||||||
#endif
|
|
||||||
|
/* don't set the second byte to NUL for a DBCS encoding, it
|
||||||
|
* has been set above */
|
||||||
|
if (enc_utf8 || !has_mbyte)
|
||||||
|
ScreenLines[off] = NUL;
|
||||||
|
|
||||||
++pos.col;
|
++pos.col;
|
||||||
++off;
|
++off;
|
||||||
}
|
}
|
||||||
@@ -2150,6 +2283,7 @@ create_vterm(term_T *term, int rows, int cols)
|
|||||||
{
|
{
|
||||||
VTerm *vterm;
|
VTerm *vterm;
|
||||||
VTermScreen *screen;
|
VTermScreen *screen;
|
||||||
|
VTermValue value;
|
||||||
|
|
||||||
vterm = vterm_new(rows, cols);
|
vterm = vterm_new(rows, cols);
|
||||||
term->tl_vterm = vterm;
|
term->tl_vterm = vterm;
|
||||||
@@ -2174,6 +2308,20 @@ create_vterm(term_T *term, int rows, int cols)
|
|||||||
|
|
||||||
/* Allow using alternate screen. */
|
/* Allow using alternate screen. */
|
||||||
vterm_screen_enable_altscreen(screen, 1);
|
vterm_screen_enable_altscreen(screen, 1);
|
||||||
|
|
||||||
|
/* For unix do not use a blinking cursor. In an xterm this causes the
|
||||||
|
* cursor to blink if it's blinking in the xterm.
|
||||||
|
* For Windows we respect the system wide setting. */
|
||||||
|
#ifdef WIN3264
|
||||||
|
if (GetCaretBlinkTime() == INFINITE)
|
||||||
|
value.boolean = 0;
|
||||||
|
else
|
||||||
|
value.boolean = 1;
|
||||||
|
#else
|
||||||
|
value.boolean = 0;
|
||||||
|
#endif
|
||||||
|
vterm_state_set_termprop(vterm_obtain_state(vterm),
|
||||||
|
VTERM_PROP_CURSORBLINK, &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2826,13 +2974,20 @@ dyn_winpty_init(int verbose)
|
|||||||
* Return OK or FAIL.
|
* Return OK or FAIL.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt)
|
term_and_job_init(
|
||||||
|
term_T *term,
|
||||||
|
int rows,
|
||||||
|
int cols,
|
||||||
|
typval_T *argvar,
|
||||||
|
jobopt_T *opt)
|
||||||
{
|
{
|
||||||
WCHAR *p = NULL;
|
WCHAR *cmd_wchar = NULL;
|
||||||
channel_T *channel = NULL;
|
channel_T *channel = NULL;
|
||||||
job_T *job = NULL;
|
job_T *job = NULL;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
HANDLE jo = NULL, child_process_handle, child_thread_handle;
|
HANDLE jo = NULL;
|
||||||
|
HANDLE child_process_handle;
|
||||||
|
HANDLE child_thread_handle;
|
||||||
void *winpty_err;
|
void *winpty_err;
|
||||||
void *spawn_config = NULL;
|
void *spawn_config = NULL;
|
||||||
char buf[MAX_PATH];
|
char buf[MAX_PATH];
|
||||||
@@ -2852,8 +3007,8 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
|
|||||||
cmd = ga.ga_data;
|
cmd = ga.ga_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = enc_to_utf16(cmd, NULL);
|
cmd_wchar = enc_to_utf16(cmd, NULL);
|
||||||
if (p == NULL)
|
if (cmd_wchar == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
job = job_alloc();
|
job = job_alloc();
|
||||||
@@ -2878,7 +3033,7 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
|
|||||||
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN |
|
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN |
|
||||||
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
|
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
|
||||||
NULL,
|
NULL,
|
||||||
p,
|
cmd_wchar,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&winpty_err);
|
&winpty_err);
|
||||||
@@ -2893,20 +3048,25 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
|
|||||||
if (job == NULL)
|
if (job == NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
/* TODO: when all lines are written and the fd is closed, the command
|
||||||
|
* doesn't get EOF and hangs. */
|
||||||
|
if (opt->jo_set & JO_IN_BUF)
|
||||||
|
job->jv_in_buf = buflist_findnr(opt->jo_io_buf[PART_IN]);
|
||||||
|
|
||||||
if (!winpty_spawn(term->tl_winpty, spawn_config, &child_process_handle,
|
if (!winpty_spawn(term->tl_winpty, spawn_config, &child_process_handle,
|
||||||
&child_thread_handle, &error, &winpty_err))
|
&child_thread_handle, &error, &winpty_err))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
channel_set_pipes(channel,
|
channel_set_pipes(channel,
|
||||||
(sock_T) CreateFileW(
|
(sock_T)CreateFileW(
|
||||||
winpty_conin_name(term->tl_winpty),
|
winpty_conin_name(term->tl_winpty),
|
||||||
GENERIC_WRITE, 0, NULL,
|
GENERIC_WRITE, 0, NULL,
|
||||||
OPEN_EXISTING, 0, NULL),
|
OPEN_EXISTING, 0, NULL),
|
||||||
(sock_T) CreateFileW(
|
(sock_T)CreateFileW(
|
||||||
winpty_conout_name(term->tl_winpty),
|
winpty_conout_name(term->tl_winpty),
|
||||||
GENERIC_READ, 0, NULL,
|
GENERIC_READ, 0, NULL,
|
||||||
OPEN_EXISTING, 0, NULL),
|
OPEN_EXISTING, 0, NULL),
|
||||||
(sock_T) CreateFileW(
|
(sock_T)CreateFileW(
|
||||||
winpty_conerr_name(term->tl_winpty),
|
winpty_conerr_name(term->tl_winpty),
|
||||||
GENERIC_READ, 0, NULL,
|
GENERIC_READ, 0, NULL,
|
||||||
OPEN_EXISTING, 0, NULL));
|
OPEN_EXISTING, 0, NULL));
|
||||||
@@ -2923,7 +3083,7 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
|
|||||||
}
|
}
|
||||||
|
|
||||||
winpty_spawn_config_free(spawn_config);
|
winpty_spawn_config_free(spawn_config);
|
||||||
vim_free(p);
|
vim_free(cmd_wchar);
|
||||||
|
|
||||||
create_vterm(term, rows, cols);
|
create_vterm(term, rows, cols);
|
||||||
|
|
||||||
@@ -2946,8 +3106,8 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
|
|||||||
failed:
|
failed:
|
||||||
if (argvar->v_type == VAR_LIST)
|
if (argvar->v_type == VAR_LIST)
|
||||||
vim_free(ga.ga_data);
|
vim_free(ga.ga_data);
|
||||||
if (p != NULL)
|
if (cmd_wchar != NULL)
|
||||||
vim_free(p);
|
vim_free(cmd_wchar);
|
||||||
if (spawn_config != NULL)
|
if (spawn_config != NULL)
|
||||||
winpty_spawn_config_free(spawn_config);
|
winpty_spawn_config_free(spawn_config);
|
||||||
if (channel != NULL)
|
if (channel != NULL)
|
||||||
@@ -3023,7 +3183,12 @@ terminal_enabled(void)
|
|||||||
* Return OK or FAIL.
|
* Return OK or FAIL.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt)
|
term_and_job_init(
|
||||||
|
term_T *term,
|
||||||
|
int rows,
|
||||||
|
int cols,
|
||||||
|
typval_T *argvar,
|
||||||
|
jobopt_T *opt)
|
||||||
{
|
{
|
||||||
create_vterm(term, rows, cols);
|
create_vterm(term, rows, cols);
|
||||||
|
|
||||||
|
|||||||
@@ -548,6 +548,19 @@ func Test_OptionSet()
|
|||||||
call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options)
|
call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options)
|
||||||
call assert_equal(g:opt[0], g:opt[1])
|
call assert_equal(g:opt[0], g:opt[1])
|
||||||
|
|
||||||
|
" 18: Setting string option"
|
||||||
|
let oldval = &tags
|
||||||
|
let g:options=[['tags', oldval, 'tagpath', 'global']]
|
||||||
|
set tags=tagpath
|
||||||
|
call assert_equal([], g:options)
|
||||||
|
call assert_equal(g:opt[0], g:opt[1])
|
||||||
|
|
||||||
|
" 1l: Resetting string option"
|
||||||
|
let g:options=[['tags', 'tagpath', oldval, 'global']]
|
||||||
|
set tags&
|
||||||
|
call assert_equal([], g:options)
|
||||||
|
call assert_equal(g:opt[0], g:opt[1])
|
||||||
|
|
||||||
" Cleanup
|
" Cleanup
|
||||||
au! OptionSet
|
au! OptionSet
|
||||||
for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
|
for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ endfunc
|
|||||||
func Test_terminal_size()
|
func Test_terminal_size()
|
||||||
let cmd = Get_cat_123_cmd()
|
let cmd = Get_cat_123_cmd()
|
||||||
|
|
||||||
exe '5terminal ' . cmd
|
exe 'terminal ++rows=5 ' . cmd
|
||||||
let size = term_getsize('')
|
let size = term_getsize('')
|
||||||
bwipe!
|
bwipe!
|
||||||
call assert_equal(5, size[0])
|
call assert_equal(5, size[0])
|
||||||
@@ -262,7 +262,7 @@ func Test_terminal_size()
|
|||||||
call assert_equal(6, size[0])
|
call assert_equal(6, size[0])
|
||||||
|
|
||||||
vsplit
|
vsplit
|
||||||
exe '5,33terminal ' . cmd
|
exe 'terminal ++rows=5 ++cols=33 ' . cmd
|
||||||
let size = term_getsize('')
|
let size = term_getsize('')
|
||||||
bwipe!
|
bwipe!
|
||||||
call assert_equal([5, 33], size)
|
call assert_equal([5, 33], size)
|
||||||
@@ -272,7 +272,7 @@ func Test_terminal_size()
|
|||||||
bwipe!
|
bwipe!
|
||||||
call assert_equal([6, 36], size)
|
call assert_equal([6, 36], size)
|
||||||
|
|
||||||
exe 'vertical 20terminal ' . cmd
|
exe 'vertical terminal ++cols=20 ' . cmd
|
||||||
let size = term_getsize('')
|
let size = term_getsize('')
|
||||||
bwipe!
|
bwipe!
|
||||||
call assert_equal(20, size[1])
|
call assert_equal(20, size[1])
|
||||||
@@ -283,7 +283,7 @@ func Test_terminal_size()
|
|||||||
call assert_equal(26, size[1])
|
call assert_equal(26, size[1])
|
||||||
|
|
||||||
split
|
split
|
||||||
exe 'vertical 6,20terminal ' . cmd
|
exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd
|
||||||
let size = term_getsize('')
|
let size = term_getsize('')
|
||||||
bwipe!
|
bwipe!
|
||||||
call assert_equal([6, 20], size)
|
call assert_equal([6, 20], size)
|
||||||
@@ -456,11 +456,23 @@ func Test_terminal_noblock()
|
|||||||
|
|
||||||
for c in ['a','b','c','d','e','f','g','h','i','j','k']
|
for c in ['a','b','c','d','e','f','g','h','i','j','k']
|
||||||
call term_sendkeys(g:buf, 'echo ' . repeat(c, 5000) . "\<cr>")
|
call term_sendkeys(g:buf, 'echo ' . repeat(c, 5000) . "\<cr>")
|
||||||
|
if has('mac')
|
||||||
|
" TODO: this should not be needed, but without it sending keys blocks
|
||||||
|
" after 8000 chars or so.
|
||||||
|
sleep 100m
|
||||||
|
endif
|
||||||
endfor
|
endfor
|
||||||
call term_sendkeys(g:buf, "echo done\<cr>")
|
call term_sendkeys(g:buf, "echo done\<cr>")
|
||||||
|
|
||||||
|
" On MS-Windows there is an extra empty line below "done". Find "done" in
|
||||||
|
" the last-but-one or the last-but-two line.
|
||||||
let g:lnum = term_getsize(g:buf)[0] - 1
|
let g:lnum = term_getsize(g:buf)[0] - 1
|
||||||
call WaitFor('term_getline(g:buf, g:lnum) =~ "done"', 3000)
|
call WaitFor('term_getline(g:buf, g:lnum) =~ "done" || term_getline(g:buf, g:lnum - 1) =~ "done"', 3000)
|
||||||
call assert_match('done', term_getline(g:buf, g:lnum))
|
let line = term_getline(g:buf, g:lnum)
|
||||||
|
if line !~ 'done'
|
||||||
|
let line = term_getline(g:buf, g:lnum - 1)
|
||||||
|
endif
|
||||||
|
call assert_match('done', line)
|
||||||
|
|
||||||
let g:job = term_getjob(g:buf)
|
let g:job = term_getjob(g:buf)
|
||||||
call Stop_shell_in_terminal(g:buf)
|
call Stop_shell_in_terminal(g:buf)
|
||||||
@@ -470,3 +482,26 @@ func Test_terminal_noblock()
|
|||||||
unlet g:lnum
|
unlet g:lnum
|
||||||
bwipe
|
bwipe
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_terminal_write_stdin()
|
||||||
|
" Todo: make this work on all systems.
|
||||||
|
if !has('unix')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
new
|
||||||
|
call setline(1, ['one', 'two', 'three'])
|
||||||
|
%term wc
|
||||||
|
call WaitFor('getline(1) != ""')
|
||||||
|
let nrs = split(getline(1))
|
||||||
|
call assert_equal(['3', '3', '14'], nrs)
|
||||||
|
bwipe
|
||||||
|
|
||||||
|
call setline(1, ['one', 'two', 'three', 'four'])
|
||||||
|
2,3term wc
|
||||||
|
call WaitFor('getline(1) != ""')
|
||||||
|
let nrs = split(getline(1))
|
||||||
|
call assert_equal(['2', '2', '10'], nrs)
|
||||||
|
bwipe
|
||||||
|
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|||||||
@@ -921,7 +921,7 @@ undo_write(bufinfo_T *bi, char_u *ptr, size_t len)
|
|||||||
static int
|
static int
|
||||||
undo_flush(bufinfo_T *bi)
|
undo_flush(bufinfo_T *bi)
|
||||||
{
|
{
|
||||||
if (bi->bi_buffer != NULL && bi->bi_used > 0)
|
if (bi->bi_buffer != NULL && bi->bi_state != NULL && bi->bi_used > 0)
|
||||||
{
|
{
|
||||||
crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used);
|
crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used);
|
||||||
if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
|
if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
|
||||||
|
|||||||
@@ -769,6 +769,68 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
995,
|
||||||
|
/**/
|
||||||
|
994,
|
||||||
|
/**/
|
||||||
|
993,
|
||||||
|
/**/
|
||||||
|
992,
|
||||||
|
/**/
|
||||||
|
991,
|
||||||
|
/**/
|
||||||
|
990,
|
||||||
|
/**/
|
||||||
|
989,
|
||||||
|
/**/
|
||||||
|
988,
|
||||||
|
/**/
|
||||||
|
987,
|
||||||
|
/**/
|
||||||
|
986,
|
||||||
|
/**/
|
||||||
|
985,
|
||||||
|
/**/
|
||||||
|
984,
|
||||||
|
/**/
|
||||||
|
983,
|
||||||
|
/**/
|
||||||
|
982,
|
||||||
|
/**/
|
||||||
|
981,
|
||||||
|
/**/
|
||||||
|
980,
|
||||||
|
/**/
|
||||||
|
979,
|
||||||
|
/**/
|
||||||
|
978,
|
||||||
|
/**/
|
||||||
|
977,
|
||||||
|
/**/
|
||||||
|
976,
|
||||||
|
/**/
|
||||||
|
975,
|
||||||
|
/**/
|
||||||
|
974,
|
||||||
|
/**/
|
||||||
|
973,
|
||||||
|
/**/
|
||||||
|
972,
|
||||||
|
/**/
|
||||||
|
971,
|
||||||
|
/**/
|
||||||
|
970,
|
||||||
|
/**/
|
||||||
|
969,
|
||||||
|
/**/
|
||||||
|
968,
|
||||||
|
/**/
|
||||||
|
967,
|
||||||
|
/**/
|
||||||
|
966,
|
||||||
|
/**/
|
||||||
|
965,
|
||||||
/**/
|
/**/
|
||||||
964,
|
964,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user