Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2018-05-10 20:51:07 -07:00
15 changed files with 512 additions and 305 deletions
+3
View File
@@ -267,6 +267,9 @@ Section "Vim executables and runtime files"
SetOutPath $0\pack\dist\opt\swapmouse\plugin
File ${VIMRT}\pack\dist\opt\swapmouse\plugin\*.*
SetOutPath $0\pack\dist\opt\termdebug\plugin
File ${VIMRT}\pack\dist\opt\termdebug\plugin\*.*
SetOutPath $0\plugin
File ${VIMRT}\plugin\*.*
+1 -1
View File
@@ -431,7 +431,7 @@ edit(
#ifdef FEAT_CONCEAL
/* Check if the cursor line needs redrawing before changing State. If
* 'concealcursor' is "n" it needs to be redrawn without concealing. */
conceal_check_cursur_line();
conceal_check_cursor_line();
#endif
#ifdef FEAT_MOUSE
+5 -1
View File
@@ -1206,7 +1206,7 @@ profile_zero(proftime_T *tm)
static timer_T *first_timer = NULL;
static long last_timer_id = 0;
static long
long
proftime_time_left(proftime_T *due, proftime_T *now)
{
# ifdef WIN3264
@@ -1424,6 +1424,10 @@ check_due_timer(void)
next_due = this_due;
}
#endif
#ifdef FEAT_TERMINAL
/* Some terminal windows may need their buffer updated. */
next_due = term_check_timers(next_due, &now);
#endif
return current_id != last_timer_id ? 1 : next_due;
}
+2 -2
View File
@@ -7830,7 +7830,7 @@ n_start_visual_mode(int c)
{
#ifdef FEAT_CONCEAL
/* Check for redraw before changing the state. */
conceal_check_cursur_line();
conceal_check_cursor_line();
#endif
VIsual_mode = c;
@@ -7857,7 +7857,7 @@ n_start_visual_mode(int c)
#endif
#ifdef FEAT_CONCEAL
/* Check for redraw after changing the state. */
conceal_check_cursur_line();
conceal_check_cursor_line();
#endif
if (p_smd && msg_silent == 0)
+2 -1
View File
@@ -1,5 +1,5 @@
/* ex_cmds2.c */
int has_watchexpr (void);
int has_watchexpr(void);
void do_debug(char_u *cmd);
void ex_debug(exarg_T *eap);
void dbg_check_breakpoint(exarg_T *eap);
@@ -19,6 +19,7 @@ float_T profile_float(proftime_T *tm);
void profile_setlimit(long msec, proftime_T *tm);
int profile_passed_limit(proftime_T *tm);
void profile_zero(proftime_T *tm);
long proftime_time_left(proftime_T *due, proftime_T *now);
timer_T *create_timer(long msec, int repeat);
long check_due_timer(void);
timer_T *find_timer(long id);
+1 -1
View File
@@ -12,7 +12,7 @@ void redrawWinline(linenr_T lnum, int invalid);
void update_curbuf(int type);
int update_screen(int type_arg);
int conceal_cursor_line(win_T *wp);
void conceal_check_cursur_line(void);
void conceal_check_cursor_line(void);
void update_single_line(win_T *wp, linenr_T lnum);
void update_debug_sign(buf_T *buf, linenr_T lnum);
void updateWindow(win_T *wp);
+1
View File
@@ -9,6 +9,7 @@ void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
int term_job_running(term_T *term);
int term_none_open(term_T *term);
int term_try_stop_job(buf_T *buf);
int term_check_timers(int next_due_arg, proftime_T *now);
int term_in_normal_mode(void);
void term_enter_job_mode(void);
int send_keys_to_term(term_T *term, int c, int typed);
+206 -135
View File
@@ -2027,7 +2027,7 @@ qf_clean_dir_stack(struct dir_stack_T **stackptr)
* Cleans up intermediate directory entries.
*
* TODO: How to solve the following problem?
* If we have the this directory tree:
* If we have this directory tree:
* ./
* ./aa
* ./aa/bb
@@ -2079,7 +2079,7 @@ qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *filename)
vim_free(ds_tmp);
}
return ds_ptr==NULL? NULL: ds_ptr->dirname;
return ds_ptr == NULL ? NULL : ds_ptr->dirname;
}
/*
@@ -2108,7 +2108,7 @@ qflist_valid (win_T *wp, int_u qf_id)
/*
* When loading a file from the quickfix, the auto commands may modify it.
* This may invalidate the current quickfix entry. This function checks
* whether a entry is still present in the quickfix.
* whether an entry is still present in the quickfix list.
* Similar to location list.
*/
static int
@@ -2272,6 +2272,21 @@ get_nth_entry(
return qf_ptr;
}
/*
* Find a window displaying a Vim help file.
*/
static win_T *
qf_find_help_win(void)
{
win_T *wp;
FOR_ALL_WINDOWS(wp)
if (bt_help(wp->w_buffer))
return wp;
return NULL;
}
/*
* Find a help window or open one.
*/
@@ -2284,9 +2299,7 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (cmdmod.tab != 0)
wp = NULL;
else
FOR_ALL_WINDOWS(wp)
if (bt_help(wp->w_buffer))
break;
wp = qf_find_help_win();
if (wp != NULL && wp->w_buffer->b_nwindows > 0)
win_enter(wp, TRUE);
else
@@ -2325,8 +2338,175 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
}
/*
* Find a suitable window for opening a file (qf_fnum) and jump to it.
* If the file is already opened in a window, jump to it.
* Find a non-quickfix window using the given location list.
* Returns NULL if a matching window is not found.
*/
static win_T *
qf_find_win_with_loclist(qf_info_T *ll)
{
win_T *wp;
FOR_ALL_WINDOWS(wp)
if (wp->w_llist == ll && !bt_quickfix(wp->w_buffer))
return wp;
return NULL;
}
/*
* Find a window containing a normal buffer
*/
static win_T *
qf_find_win_with_normal_buf(void)
{
win_T *wp;
FOR_ALL_WINDOWS(wp)
if (wp->w_buffer->b_p_bt[0] == NUL)
return wp;
return NULL;
}
/*
* Go to a window in any tabpage containing the specified file. Returns TRUE
* if successfully jumped to the window. Otherwise returns FALSE.
*/
static int
qf_goto_tabwin_with_file(int fnum)
{
tabpage_T *tp;
win_T *wp;
FOR_ALL_TAB_WINDOWS(tp, wp)
if (wp->w_buffer->b_fnum == fnum)
{
goto_tabpage_win(tp, wp);
return TRUE;
}
return FALSE;
}
/*
* Create a new window to show a file above the quickfix window. Called when
* only the quickfix window is present.
*/
static int
qf_open_new_file_win(qf_info_T *ll_ref)
{
int flags;
flags = WSP_ABOVE;
if (ll_ref != NULL)
flags |= WSP_NEWLOC;
if (win_split(0, flags) == FAIL)
return FAIL; /* not enough room for window */
p_swb = empty_option; /* don't split again */
swb_flags = 0;
RESET_BINDING(curwin);
if (ll_ref != NULL)
{
/* The new window should use the location list from the
* location list window */
curwin->w_llist = ll_ref;
ll_ref->qf_refcount++;
}
return OK;
}
/*
* Go to a window that shows the right buffer. If the window is not found, go
* to the window just above the location list window. This is used for opening
* a file from a location window and not from a quickfix window. If some usable
* window is previously found, then it is supplied in 'use_win'.
*/
static void
qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref)
{
win_T *win = use_win;
if (win == NULL)
{
/* Find the window showing the selected file */
FOR_ALL_WINDOWS(win)
if (win->w_buffer->b_fnum == qf_fnum)
break;
if (win == NULL)
{
/* Find a previous usable window */
win = curwin;
do
{
if (win->w_buffer->b_p_bt[0] == NUL)
break;
if (win->w_prev == NULL)
win = lastwin; /* wrap around the top */
else
win = win->w_prev; /* go to previous window */
} while (win != curwin);
}
}
win_goto(win);
/* If the location list for the window is not set, then set it
* to the location list from the location window */
if (win->w_llist == NULL)
{
win->w_llist = ll_ref;
ll_ref->qf_refcount++;
}
}
/*
* Go to a window that shows the specified file. If a window is not found, go
* to the window just above the quickfix window. This is used for opening a
* file from a quickfix window and not from a location window.
*/
static void
qf_goto_win_with_qfl_file(int qf_fnum)
{
win_T *win;
win_T *altwin;
win = curwin;
altwin = NULL;
for (;;)
{
if (win->w_buffer->b_fnum == qf_fnum)
break;
if (win->w_prev == NULL)
win = lastwin; /* wrap around the top */
else
win = win->w_prev; /* go to previous window */
if (IS_QF_WINDOW(win))
{
/* Didn't find it, go to the window before the quickfix
* window. */
if (altwin != NULL)
win = altwin;
else if (curwin->w_prev != NULL)
win = curwin->w_prev;
else
win = curwin->w_next;
break;
}
/* Remember a usable window. */
if (altwin == NULL && !win->w_p_pvw
&& win->w_buffer->b_p_bt[0] == NUL)
altwin = win;
}
win_goto(win);
}
/*
* Find a suitable window for opening a file (qf_fnum) from the
* quickfix/location list and jump to it. If the file is already opened in a
* window, jump to it. Otherwise open a new window to display the file. This is
* called from either a quickfix or a location list window.
*/
static int
qf_jump_to_usable_window(int qf_fnum, int *opened_window)
@@ -2334,35 +2514,25 @@ qf_jump_to_usable_window(int qf_fnum, int *opened_window)
win_T *usable_win_ptr = NULL;
int usable_win;
qf_info_T *ll_ref;
int flags;
win_T *win;
win_T *altwin;
usable_win = 0;
ll_ref = curwin->w_llist_ref;
if (ll_ref != NULL)
{
/* Find a window using the same location list that is not a
* quickfix window. */
FOR_ALL_WINDOWS(usable_win_ptr)
if (usable_win_ptr->w_llist == ll_ref
&& !bt_quickfix(usable_win_ptr->w_buffer))
{
usable_win = 1;
break;
}
/* Find a non-quickfix window with this location list */
usable_win_ptr = qf_find_win_with_loclist(ll_ref);
if (usable_win_ptr != NULL)
usable_win = 1;
}
if (!usable_win)
{
/* Locate a window showing a normal buffer */
FOR_ALL_WINDOWS(win)
if (win->w_buffer->b_p_bt[0] == NUL)
{
usable_win = 1;
break;
}
win = qf_find_win_with_normal_buf();
if (win != NULL)
usable_win = 1;
}
/*
@@ -2370,21 +2540,7 @@ qf_jump_to_usable_window(int qf_fnum, int *opened_window)
* then search in other tabs.
*/
if (!usable_win && (swb_flags & SWB_USETAB))
{
tabpage_T *tp;
win_T *wp;
FOR_ALL_TAB_WINDOWS(tp, wp)
{
if (wp->w_buffer->b_fnum == qf_fnum)
{
goto_tabpage_win(tp, wp);
usable_win = 1;
goto win_found;
}
}
}
win_found:
usable_win = qf_goto_tabwin_with_file(qf_fnum);
/*
* If there is only one window and it is the quickfix window, create a
@@ -2392,99 +2548,16 @@ win_found:
*/
if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win)
{
flags = WSP_ABOVE;
if (ll_ref != NULL)
flags |= WSP_NEWLOC;
if (win_split(0, flags) == FAIL)
return FAIL; /* not enough room for window */
if (qf_open_new_file_win(ll_ref) != OK)
return FAIL;
*opened_window = TRUE; /* close it when fail */
p_swb = empty_option; /* don't split again */
swb_flags = 0;
RESET_BINDING(curwin);
if (ll_ref != NULL)
{
/* The new window should use the location list from the
* location list window */
curwin->w_llist = ll_ref;
ll_ref->qf_refcount++;
}
}
else
{
if (curwin->w_llist_ref != NULL)
{
/* In a location window */
win = usable_win_ptr;
if (win == NULL)
{
/* Find the window showing the selected file */
FOR_ALL_WINDOWS(win)
if (win->w_buffer->b_fnum == qf_fnum)
break;
if (win == NULL)
{
/* Find a previous usable window */
win = curwin;
do
{
if (win->w_buffer->b_p_bt[0] == NUL)
break;
if (win->w_prev == NULL)
win = lastwin; /* wrap around the top */
else
win = win->w_prev; /* go to previous window */
} while (win != curwin);
}
}
win_goto(win);
/* If the location list for the window is not set, then set it
* to the location list from the location window */
if (win->w_llist == NULL)
{
win->w_llist = ll_ref;
ll_ref->qf_refcount++;
}
}
else
{
/*
* Try to find a window that shows the right buffer.
* Default to the window just above the quickfix buffer.
*/
win = curwin;
altwin = NULL;
for (;;)
{
if (win->w_buffer->b_fnum == qf_fnum)
break;
if (win->w_prev == NULL)
win = lastwin; /* wrap around the top */
else
win = win->w_prev; /* go to previous window */
if (IS_QF_WINDOW(win))
{
/* Didn't find it, go to the window before the quickfix
* window. */
if (altwin != NULL)
win = altwin;
else if (curwin->w_prev != NULL)
win = curwin->w_prev;
else
win = curwin->w_next;
break;
}
/* Remember a usable window. */
if (altwin == NULL && !win->w_p_pvw
&& win->w_buffer->b_p_bt[0] == NUL)
altwin = win;
}
win_goto(win);
}
if (curwin->w_llist_ref != NULL) /* In a location window */
qf_goto_win_with_ll_file(usable_win_ptr, qf_fnum, ll_ref);
else /* In a quickfix window */
qf_goto_win_with_qfl_file(qf_fnum);
}
return OK;
@@ -2562,8 +2635,8 @@ qf_jump_edit_buffer(
}
/*
* Goto the error line in the current file using either line/column number or a
* search pattern.
* Go to the error line in the current file using either line/column number or
* a search pattern.
*/
static void
qf_jump_goto_line(
@@ -5779,7 +5852,7 @@ qf_setprop_context(qf_info_T *qi, int qf_idx, dictitem_T *di)
/*
* Set quickfix/location list properties (title, items, context).
* Also used to add items from parsing a list of lines.
* Used by the setqflist() and setloclist() VimL functions.
* Used by the setqflist() and setloclist() Vim script functions.
*/
static int
qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
@@ -6162,9 +6235,7 @@ hgr_get_ll(int *new_ll)
wp = curwin;
else
/* Find an existing help window */
FOR_ALL_WINDOWS(wp)
if (bt_help(wp->w_buffer))
break;
wp = qf_find_help_win();
if (wp == NULL) /* Help window not found */
qi = NULL;
+1 -1
View File
@@ -906,7 +906,7 @@ conceal_cursor_line(win_T *wp)
* Check if the cursor line needs to be redrawn because of 'concealcursor'.
*/
void
conceal_check_cursur_line(void)
conceal_check_cursor_line(void)
{
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin))
{
+149 -138
View File
@@ -1550,6 +1550,152 @@ static char *(key_names[]) =
};
#endif
#ifdef HAVE_TGETENT
static void
get_term_entries(int *height, int *width)
{
static struct {
enum SpecialKey dest; /* index in term_strings[] */
char *name; /* termcap name for string */
} string_names[] =
{ {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
{KS_CL, "cl"}, {KS_CD, "cd"},
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
{KS_ME, "me"}, {KS_MR, "mr"},
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
{KS_STE,"Te"}, {KS_STS,"Ts"},
{KS_CM, "cm"}, {KS_SR, "sr"},
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
{KS_VS, "vs"}, {KS_CVS, "VS"},
{KS_CIS, "IS"}, {KS_CIE, "IE"},
{KS_CSC, "SC"}, {KS_CEC, "EC"},
{KS_TS, "ts"}, {KS_FS, "fs"},
{KS_CWP, "WP"}, {KS_CWS, "WS"},
{KS_CSI, "SI"}, {KS_CEI, "EI"},
{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
{KS_8F, "8f"}, {KS_8B, "8b"},
{KS_CBE, "BE"}, {KS_CBD, "BD"},
{KS_CPS, "PS"}, {KS_CPE, "PE"},
{(enum SpecialKey)0, NULL}
};
int i;
char_u *p;
static char_u tstrbuf[TBUFSZ];
char_u *tp = tstrbuf;
/*
* get output strings
*/
for (i = 0; string_names[i].name != NULL; ++i)
{
if (TERM_STR(string_names[i].dest) == NULL
|| TERM_STR(string_names[i].dest) == empty_option)
TERM_STR(string_names[i].dest) = TGETSTR(string_names[i].name, &tp);
}
/* tgetflag() returns 1 if the flag is present, 0 if not and
* possibly -1 if the flag doesn't exist. */
if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms") > 0)
T_MS = (char_u *)"y";
if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs") > 0)
T_XS = (char_u *)"y";
if ((T_XN == NULL || T_XN == empty_option) && tgetflag("xn") > 0)
T_XN = (char_u *)"y";
if ((T_DB == NULL || T_DB == empty_option) && tgetflag("db") > 0)
T_DB = (char_u *)"y";
if ((T_DA == NULL || T_DA == empty_option) && tgetflag("da") > 0)
T_DA = (char_u *)"y";
if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut") > 0)
T_UT = (char_u *)"y";
/*
* get key codes
*/
for (i = 0; key_names[i] != NULL; ++i)
if (find_termcode((char_u *)key_names[i]) == NULL)
{
p = TGETSTR(key_names[i], &tp);
/* if cursor-left == backspace, ignore it (televideo 925) */
if (p != NULL
&& (*p != Ctrl_H
|| key_names[i][0] != 'k'
|| key_names[i][1] != 'l'))
add_termcode((char_u *)key_names[i], p, FALSE);
}
if (*height == 0)
*height = tgetnum("li");
if (*width == 0)
*width = tgetnum("co");
/*
* Get number of colors (if not done already).
*/
if (TERM_STR(KS_CCO) == NULL || TERM_STR(KS_CCO) == empty_option)
set_color_count(tgetnum("Co"));
# ifndef hpux
BC = (char *)TGETSTR("bc", &tp);
UP = (char *)TGETSTR("up", &tp);
p = TGETSTR("pc", &tp);
if (p)
PC = *p;
# endif
}
#endif
static void
report_term_error(char_u *error_msg, char_u *term)
{
struct builtin_term *termp;
mch_errmsg("\r\n");
if (error_msg != NULL)
{
mch_errmsg((char *)error_msg);
mch_errmsg("\r\n");
}
mch_errmsg("'");
mch_errmsg((char *)term);
mch_errmsg(_("' not known. Available builtin terminals are:"));
mch_errmsg("\r\n");
for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL; ++termp)
{
if (termp->bt_entry == (int)KS_NAME)
{
#ifdef HAVE_TGETENT
mch_errmsg(" builtin_");
#else
mch_errmsg(" ");
#endif
mch_errmsg(termp->bt_string);
mch_errmsg("\r\n");
}
}
}
static void
report_default_term(char_u *term)
{
mch_errmsg(_("defaulting to '"));
mch_errmsg((char *)term);
mch_errmsg("'\r\n");
if (emsg_silent == 0)
{
screen_start(); /* don't know where cursor is now */
out_flush();
if (!is_not_a_term())
ui_delay(2000L, TRUE);
}
}
/*
* Set terminal options for terminal "term".
* Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
@@ -1601,42 +1747,7 @@ set_termname(char_u *term)
*/
if (try == 1)
{
char_u *p;
static char_u tstrbuf[TBUFSZ];
int i;
char_u tbuf[TBUFSZ];
char_u *tp;
static struct {
enum SpecialKey dest; /* index in term_strings[] */
char *name; /* termcap name for string */
} string_names[] =
{ {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
{KS_CL, "cl"}, {KS_CD, "cd"},
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
{KS_ME, "me"}, {KS_MR, "mr"},
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
{KS_STE,"Te"}, {KS_STS,"Ts"},
{KS_CM, "cm"}, {KS_SR, "sr"},
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
{KS_VS, "vs"}, {KS_CVS, "VS"},
{KS_CIS, "IS"}, {KS_CIE, "IE"},
{KS_CSC, "SC"}, {KS_CEC, "EC"},
{KS_TS, "ts"}, {KS_FS, "fs"},
{KS_CWP, "WP"}, {KS_CWS, "WS"},
{KS_CSI, "SI"}, {KS_CEI, "EI"},
{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
{KS_8F, "8f"}, {KS_8B, "8b"},
{KS_CBE, "BE"}, {KS_CBD, "BD"},
{KS_CPS, "PS"}, {KS_CPE, "PE"},
{(enum SpecialKey)0, NULL}
};
/*
* If the external termcap does not have a matching entry, try the
@@ -1644,81 +1755,13 @@ set_termname(char_u *term)
*/
if ((error_msg = tgetent_error(tbuf, term)) == NULL)
{
tp = tstrbuf;
if (!termcap_cleared)
{
clear_termoptions(); /* clear old options */
termcap_cleared = TRUE;
}
/* get output strings */
for (i = 0; string_names[i].name != NULL; ++i)
{
if (TERM_STR(string_names[i].dest) == NULL
|| TERM_STR(string_names[i].dest) == empty_option)
TERM_STR(string_names[i].dest) =
TGETSTR(string_names[i].name, &tp);
}
/* tgetflag() returns 1 if the flag is present, 0 if not and
* possibly -1 if the flag doesn't exist. */
if ((T_MS == NULL || T_MS == empty_option)
&& tgetflag("ms") > 0)
T_MS = (char_u *)"y";
if ((T_XS == NULL || T_XS == empty_option)
&& tgetflag("xs") > 0)
T_XS = (char_u *)"y";
if ((T_XN == NULL || T_XN == empty_option)
&& tgetflag("xn") > 0)
T_XN = (char_u *)"y";
if ((T_DB == NULL || T_DB == empty_option)
&& tgetflag("db") > 0)
T_DB = (char_u *)"y";
if ((T_DA == NULL || T_DA == empty_option)
&& tgetflag("da") > 0)
T_DA = (char_u *)"y";
if ((T_UT == NULL || T_UT == empty_option)
&& tgetflag("ut") > 0)
T_UT = (char_u *)"y";
/*
* get key codes
*/
for (i = 0; key_names[i] != NULL; ++i)
{
if (find_termcode((char_u *)key_names[i]) == NULL)
{
p = TGETSTR(key_names[i], &tp);
/* if cursor-left == backspace, ignore it (televideo
* 925) */
if (p != NULL
&& (*p != Ctrl_H
|| key_names[i][0] != 'k'
|| key_names[i][1] != 'l'))
add_termcode((char_u *)key_names[i], p, FALSE);
}
}
if (height == 0)
height = tgetnum("li");
if (width == 0)
width = tgetnum("co");
/*
* Get number of colors (if not done already).
*/
if (TERM_STR(KS_CCO) == NULL
|| TERM_STR(KS_CCO) == empty_option)
set_color_count(tgetnum("Co"));
# ifndef hpux
BC = (char *)TGETSTR("bc", &tp);
UP = (char *)TGETSTR("up", &tp);
p = TGETSTR("pc", &tp);
if (p)
PC = *p;
# endif /* hpux */
get_term_entries(&height, &width);
}
}
else /* try == 0 || try == 2 */
@@ -1754,31 +1797,8 @@ set_termname(char_u *term)
if (termcap_cleared) /* found in external termcap */
break;
#endif
report_term_error(error_msg, term);
mch_errmsg("\r\n");
if (error_msg != NULL)
{
mch_errmsg((char *)error_msg);
mch_errmsg("\r\n");
}
mch_errmsg("'");
mch_errmsg((char *)term);
mch_errmsg(_("' not known. Available builtin terminals are:"));
mch_errmsg("\r\n");
for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
++termp)
{
if (termp->bt_entry == (int)KS_NAME)
{
#ifdef HAVE_TGETENT
mch_errmsg(" builtin_");
#else
mch_errmsg(" ");
#endif
mch_errmsg(termp->bt_string);
mch_errmsg("\r\n");
}
}
/* when user typed :set term=xxx, quit here */
if (starting != NO_SCREEN)
{
@@ -1787,16 +1807,7 @@ set_termname(char_u *term)
return FAIL;
}
term = DEFAULT_TERM;
mch_errmsg(_("defaulting to '"));
mch_errmsg((char *)term);
mch_errmsg("'\r\n");
if (emsg_silent == 0)
{
screen_start(); /* don't know where cursor is now */
out_flush();
if (!is_not_a_term())
ui_delay(2000L, TRUE);
}
report_default_term(term);
set_string_option_direct((char_u *)"term", -1, term,
OPT_FREE, 0);
display_errors();
+105 -18
View File
@@ -43,8 +43,6 @@
* - Win32: Redirecting output works but includes escape sequences.
* - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
* redirection.
* - Copy text in the vterm to the Vim buffer once in a while, so that
* completion works.
* - When the job only outputs lines, we could handle resizing the terminal
* better: store lines separated by line breaks, instead of screen lines,
* then when the window is resized redraw those lines.
@@ -131,7 +129,11 @@ struct terminal_S {
/* Range of screen rows to update. Zero based. */
int tl_dirty_row_start; /* MAX_ROW if nothing dirty */
int tl_dirty_row_end; /* row below last one to update */
int tl_dirty_snapshot; /* text updated after making snapshot */
#ifdef FEAT_TIMERS
int tl_timer_set;
proftime_T tl_timer_due;
#endif
int tl_postponed_scroll; /* to be scrolled up */
garray_T tl_scrollback;
@@ -1446,6 +1448,29 @@ add_empty_scrollback(term_T *term, cellattr_T *fill_attr, int lnum)
return FALSE;
}
/*
* Remove the terminal contents from the scrollback and the buffer.
* Used before adding a new scrollback line or updating the buffer for lines
* displayed in the terminal.
*/
static void
cleanup_scrollback(term_T *term)
{
sb_line_T *line;
garray_T *gap;
gap = &term->tl_scrollback;
while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
&& gap->ga_len > 0)
{
ml_delete(curbuf->b_ml.ml_line_count, FALSE);
line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
vim_free(line->sb_cells);
--gap->ga_len;
}
check_cursor();
}
/*
* Add the current lines of the terminal to scrollback and to the buffer.
* Called after the job has ended and when switching to Terminal-Normal mode.
@@ -1464,9 +1489,22 @@ move_terminal_to_buffer(term_T *term)
if (term->tl_vterm == NULL)
return;
/* Nothing to do if the buffer already has the lines and nothing was
* changed. */
if (!term->tl_dirty_snapshot
&& curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled)
return;
ch_log(term->tl_job == NULL ? NULL : term->tl_job->jv_channel,
"Adding terminal window snapshot to buffer");
/* First remove the lines that were appended before, they might be
* outdated. */
cleanup_scrollback(term);
screen = vterm_obtain_screen(term->tl_vterm);
fill_attr = new_fill_attr = term->tl_default_color;
for (pos.row = 0; pos.row < term->tl_rows; ++pos.row)
{
len = 0;
@@ -1553,6 +1591,11 @@ move_terminal_to_buffer(term_T *term)
}
}
term->tl_dirty_snapshot = FALSE;
#ifdef FEAT_TIMERS
term->tl_timer_set = FALSE;
#endif
/* Obtain the current background color. */
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
&term->tl_default_color.fg, &term->tl_default_color.bg);
@@ -1576,6 +1619,38 @@ move_terminal_to_buffer(term_T *term)
}
}
#if defined(FEAT_TIMERS) || defined(PROTO)
/*
* Check if any terminal timer expired. If so, copy text from the terminal to
* the buffer.
* Return the time until the next timer will expire.
*/
int
term_check_timers(int next_due_arg, proftime_T *now)
{
term_T *term;
int next_due = next_due_arg;
for (term = first_term; term != NULL; term = term->tl_next)
{
if (term->tl_timer_set && !term->tl_normal_mode)
{
long this_due = proftime_time_left(&term->tl_timer_due, now);
if (this_due <= 1)
{
term->tl_timer_set = FALSE;
move_terminal_to_buffer(term);
}
else if (next_due == -1 || next_due > this_due)
next_due = this_due;
}
}
return next_due;
}
#endif
static void
set_terminal_mode(term_T *term, int normal_mode)
{
@@ -1643,20 +1718,6 @@ term_in_normal_mode(void)
term_enter_job_mode()
{
term_T *term = curbuf->b_term;
sb_line_T *line;
garray_T *gap;
/* Remove the terminal contents from the scrollback and the buffer. */
gap = &term->tl_scrollback;
while (curbuf->b_ml.ml_line_count > term->tl_scrollback_scrolled
&& gap->ga_len > 0)
{
ml_delete(curbuf->b_ml.ml_line_count, FALSE);
line = (sb_line_T *)gap->ga_data + gap->ga_len - 1;
vim_free(line->sb_cells);
--gap->ga_len;
}
check_cursor();
set_terminal_mode(term, FALSE);
@@ -2179,6 +2240,12 @@ theend:
in_terminal_loop = NULL;
if (restore_cursor)
prepare_restore_cursor_props();
/* Move a snapshot of the screen contents to the buffer, so that completion
* works in other buffers. */
if (curbuf->b_term != NULL)
move_terminal_to_buffer(curbuf->b_term);
return ret;
}
@@ -2395,6 +2462,20 @@ cell2attr(VTermScreenCellAttrs cellattrs, VTermColor cellfg, VTermColor cellbg)
return 0;
}
static void
set_dirty_snapshot(term_T *term)
{
term->tl_dirty_snapshot = TRUE;
#ifdef FEAT_TIMERS
if (!term->tl_normal_mode)
{
/* Update the snapshot after 100 msec of not getting updates. */
profile_setlimit(100L, &term->tl_timer_due);
term->tl_timer_set = TRUE;
}
#endif
}
static int
handle_damage(VTermRect rect, void *user)
{
@@ -2402,6 +2483,7 @@ handle_damage(VTermRect rect, void *user)
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, rect.start_row);
term->tl_dirty_row_end = MAX(term->tl_dirty_row_end, rect.end_row);
set_dirty_snapshot(term);
redraw_buf_later(term->tl_buffer, SOME_VALID);
return 1;
}
@@ -2448,6 +2530,7 @@ handle_moverect(VTermRect dest, VTermRect src, void *user)
term->tl_dirty_row_start = MIN(term->tl_dirty_row_start, dest.start_row);
term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row);
set_dirty_snapshot(term);
/* Note sure if the scrolling will work correctly, let's do a complete
* redraw later. */
@@ -2599,6 +2682,10 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
{
term_T *term = (term_T *)user;
/* First remove the lines that were appended before, the pushed line goes
* above it. */
cleanup_scrollback(term);
/* If the number of lines that are stored goes over 'termscrollback' then
* delete the first 10%. */
if (term->tl_scrollback.ga_len >= term->tl_buffer->b_p_twsl)
+2 -2
View File
@@ -284,7 +284,7 @@ func Test_set_ttytype()
" in travis on some builds. Why? Catch both for now
try
set ttytype=
call assert_report('set ttype= did not fail')
call assert_report('set ttytype= did not fail')
catch /E529\|E522/
endtry
@@ -292,7 +292,7 @@ func Test_set_ttytype()
" check for failure of finding the entry and for missing 'cm' entry.
try
set ttytype=xxx
call assert_report('set ttype=xxx did not fail')
call assert_report('set ttytype=xxx did not fail')
catch /E522\|E437/
endtry
+19 -4
View File
@@ -17,7 +17,7 @@ func Test_window_cmd_ls0_with_split()
endfunc
func Test_window_cmd_cmdwin_with_vsp()
let efmt='Expected 0 but got %d (in ls=%d, %s window)'
let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
for v in range(0, 2)
exec "set ls=" . v
vsplit
@@ -444,21 +444,21 @@ func Test_window_contents()
exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
redraw
let s3=GetScreenStr(1)
let s3 = GetScreenStr(1)
wincmd p
call assert_equal(1, line("w0"))
call assert_equal('1 ', s3)
exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
redraw
let s3=GetScreenStr(1)
let s3 = GetScreenStr(1)
wincmd p
call assert_equal(50, line("w0"))
call assert_equal('50 ', s3)
exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
redraw
let s3=GetScreenStr(1)
let s3 = GetScreenStr(1)
wincmd p
call assert_equal(59, line("w0"))
call assert_equal('59 ', s3)
@@ -507,4 +507,19 @@ func Test_visual_cleared_after_window_split()
bwipe!
endfunc
func Test_winrestcmd()
2split
3vsplit
let a = winrestcmd()
call assert_equal(2, winheight(0))
call assert_equal(3, winwidth(0))
wincmd =
call assert_notequal(2, winheight(0))
call assert_notequal(3, winwidth(0))
exe a
call assert_equal(2, winheight(0))
call assert_equal(3, winwidth(0))
only
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+1 -1
View File
@@ -1991,7 +1991,7 @@ ui_cursor_shape_forced(int forced)
# endif
# ifdef FEAT_CONCEAL
conceal_check_cursur_line();
conceal_check_cursor_line();
# endif
}
+14
View File
@@ -776,6 +776,20 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1813,
/**/
1812,
/**/
1811,
/**/
1810,
/**/
1809,
/**/
1808,
/**/
1807,
/**/
1806,
/**/