1
0
forked from aniani/vim

patch 8.0.0877: using CTRL-\ CTRL-N in terminal is inconsistent

Problem:    Using CTRL-\ CTRL-N in terminal is inconsistent.
Solution:   Stay in Normal mode.
This commit is contained in:
Bram Moolenaar
2017-08-06 14:57:49 +02:00
parent 39d21e3c30
commit 6d8197485d
6 changed files with 55 additions and 63 deletions

View File

@@ -1356,13 +1356,13 @@ main_loop(
else else
{ {
#ifdef FEAT_TERMINAL #ifdef FEAT_TERMINAL
if (term_use_loop(TRUE) if (term_use_loop()
&& oa.op_type == OP_NOP && oa.regname == NUL && oa.op_type == OP_NOP && oa.regname == NUL
&& !VIsual_active) && !VIsual_active)
{ {
/* If terminal_loop() returns OK we got a key that is handled /* If terminal_loop() returns OK we got a key that is handled
* in Normal model. With FAIL the terminal was closed and the * in Normal model. With FAIL we first need to position the
* screen needs to be redrawn. */ * cursor and the screen needs to be redrawn. */
if (terminal_loop() == OK) if (terminal_loop() == OK)
normal_cmd(&oa, TRUE); normal_cmd(&oa, TRUE);
} }

View File

@@ -4639,7 +4639,7 @@ nv_mousescroll(cmdarg_T *cap)
if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN)
{ {
# ifdef FEAT_TERMINAL # ifdef FEAT_TERMINAL
if (term_use_loop(FALSE)) if (term_use_loop())
send_keys_to_term(curbuf->b_term, cap->cmdchar, TRUE); send_keys_to_term(curbuf->b_term, cap->cmdchar, TRUE);
else else
# endif # endif
@@ -9061,10 +9061,10 @@ nv_edit(cmdarg_T *cap)
#endif #endif
} }
#ifdef FEAT_TERMINAL #ifdef FEAT_TERMINAL
else if (term_in_terminal_mode()) else if (term_in_normal_mode())
{ {
clearop(cap->oap); clearop(cap->oap);
term_leave_terminal_mode(); term_enter_job_mode();
return; return;
} }
#endif #endif

View File

@@ -8228,7 +8228,7 @@ set_bool_option(
{ {
# ifdef FEAT_TERMINAL # ifdef FEAT_TERMINAL
/* Cannot set 'modifiable' when in Terminal mode. */ /* Cannot set 'modifiable' when in Terminal mode. */
if (term_in_terminal_mode() if (term_in_normal_mode()
|| (bt_terminal(curbuf) && !term_is_finished(curbuf))) || (bt_terminal(curbuf) && !term_is_finished(curbuf)))
{ {
curbuf->b_p_ma = FALSE; curbuf->b_p_ma = FALSE;

View File

@@ -3,10 +3,10 @@ void ex_terminal(exarg_T *eap);
void free_terminal(buf_T *buf); void free_terminal(buf_T *buf);
void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
int term_job_running(term_T *term); int term_job_running(term_T *term);
int term_in_terminal_mode(void); int term_in_normal_mode(void);
void term_leave_terminal_mode(void); void term_enter_job_mode(void);
int send_keys_to_term(term_T *term, int c, int typed); int send_keys_to_term(term_T *term, int c, int typed);
int term_use_loop(int once); int term_use_loop(void);
int terminal_loop(void); int terminal_loop(void);
void term_job_ended(job_T *job); void term_job_ended(job_T *job);
void term_channel_closed(channel_T *ch); void term_channel_closed(channel_T *ch);

View File

@@ -36,8 +36,7 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback. * that buffer, attributes come from the scrollback buffer tl_scrollback.
* *
* TODO: * TODO:
* - MS-Windows: no redraw for 'updatetime' #1915 * - Add argument to term_wait() for waiting time.
* - add argument to term_wait() for waiting time.
* - For the scrollback buffer store lines in the buffer, only attributes in * - For the scrollback buffer store lines in the buffer, only attributes in
* tl_scrollback. * tl_scrollback.
* - When the job ends: * - When the job ends:
@@ -47,6 +46,7 @@
* - add option values to the command: * - add option values to the command:
* :term <24x80> <close> vim notes.txt * :term <24x80> <close> vim notes.txt
* - support different cursor shapes, colors and attributes * - support different cursor shapes, colors and attributes
* - MS-Windows: no redraw for 'updatetime' #1915
* - make term_getcursor() return type (none/block/bar/underline) and * - make term_getcursor() return type (none/block/bar/underline) and
* attributes (color, blink, etc.) * attributes (color, blink, etc.)
* - To set BS correctly, check get_stty(); Pass the fd of the pty. * - To set BS correctly, check get_stty(); Pass the fd of the pty.
@@ -115,7 +115,7 @@ struct terminal_S {
int tl_tty_fd; int tl_tty_fd;
char_u *tl_tty_name; char_u *tl_tty_name;
int tl_terminal_mode; /* 0, TMODE_ONCE or TMODE_LOOP */ int tl_normal_mode; /* TRUE: Terminal-Normal mode */
int tl_channel_closed; int tl_channel_closed;
#ifdef WIN3264 #ifdef WIN3264
@@ -462,7 +462,7 @@ term_write_job_output(term_T *term, char_u *msg, size_t len)
static void static void
update_cursor(term_T *term, int redraw) update_cursor(term_T *term, int redraw)
{ {
if (term->tl_terminal_mode != 0) if (term->tl_normal_mode)
return; return;
setcursor(); setcursor();
if (redraw && term->tl_buffer == curbuf) if (redraw && term->tl_buffer == curbuf)
@@ -495,7 +495,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
ch_log(channel, "writing %d bytes to terminal", (int)len); ch_log(channel, "writing %d bytes to terminal", (int)len);
term_write_job_output(term, msg, len); term_write_job_output(term, msg, len);
if (term->tl_terminal_mode == 0) if (!term->tl_normal_mode)
{ {
/* TODO: only update once in a while. */ /* TODO: only update once in a while. */
update_screen(0); update_screen(0);
@@ -808,9 +808,9 @@ move_terminal_to_buffer(term_T *term)
} }
static void static void
set_terminal_mode(term_T *term, int mode) set_terminal_mode(term_T *term, int normal_mode)
{ {
term->tl_terminal_mode = mode; term->tl_normal_mode = normal_mode;
vim_free(term->tl_status_text); vim_free(term->tl_status_text);
term->tl_status_text = NULL; term->tl_status_text = NULL;
if (term->tl_buffer == curbuf) if (term->tl_buffer == curbuf)
@@ -826,7 +826,7 @@ cleanup_vterm(term_T *term)
{ {
move_terminal_to_buffer(term); move_terminal_to_buffer(term);
term_free_vterm(term); term_free_vterm(term);
set_terminal_mode(term, 0); set_terminal_mode(term, FALSE);
} }
/* /*
@@ -834,17 +834,15 @@ cleanup_vterm(term_T *term)
* Suspends updating the terminal window. * Suspends updating the terminal window.
*/ */
static void static void
term_enter_terminal_mode(int mode) term_enter_normal_mode(void)
{ {
term_T *term = curbuf->b_term; term_T *term = curbuf->b_term;
/* Append the current terminal contents to the buffer. */ /* Append the current terminal contents to the buffer. */
move_terminal_to_buffer(term); move_terminal_to_buffer(term);
set_terminal_mode(term, mode); set_terminal_mode(term, TRUE);
if (mode == TMODE_ONCE)
{
/* Move the window cursor to the position of the cursor in the /* Move the window cursor to the position of the cursor in the
* terminal. */ * terminal. */
curwin->w_cursor.lnum = term->tl_scrollback_scrolled curwin->w_cursor.lnum = term->tl_scrollback_scrolled
@@ -855,18 +853,17 @@ term_enter_terminal_mode(int mode)
/* Display the same lines as in the terminal. */ /* Display the same lines as in the terminal. */
curwin->w_topline = term->tl_scrollback_scrolled + 1; curwin->w_topline = term->tl_scrollback_scrolled + 1;
} }
}
/* /*
* Returns TRUE if the current window contains a terminal and we are in * Returns TRUE if the current window contains a terminal and we are in
* Terminal-Normal mode. * Terminal-Normal mode.
*/ */
int int
term_in_terminal_mode() term_in_normal_mode(void)
{ {
term_T *term = curbuf->b_term; term_T *term = curbuf->b_term;
return term != NULL && term->tl_terminal_mode != 0; return term != NULL && term->tl_normal_mode;
} }
/* /*
@@ -874,7 +871,7 @@ term_in_terminal_mode()
* Restores updating the terminal window. * Restores updating the terminal window.
*/ */
void void
term_leave_terminal_mode() term_enter_job_mode()
{ {
term_T *term = curbuf->b_term; term_T *term = curbuf->b_term;
sb_line_T *line; sb_line_T *line;
@@ -893,7 +890,7 @@ term_leave_terminal_mode()
} }
check_cursor(); check_cursor();
set_terminal_mode(term, 0); set_terminal_mode(term, FALSE);
if (term->tl_channel_closed) if (term->tl_channel_closed)
cleanup_vterm(term); cleanup_vterm(term);
@@ -1053,13 +1050,12 @@ term_paste_register(int prev_c UNUSED)
* keys to the job. * keys to the job.
*/ */
int int
term_use_loop(int once) term_use_loop(void)
{ {
term_T *term = curbuf->b_term; term_T *term = curbuf->b_term;
return term != NULL return term != NULL
&& (once ? term->tl_terminal_mode != TMODE_LOOP && !term->tl_normal_mode
: term->tl_terminal_mode == 0)
&& term->tl_vterm != NULL && term->tl_vterm != NULL
&& term_job_running(term); && term_job_running(term);
} }
@@ -1077,13 +1073,6 @@ terminal_loop(void)
int c; int c;
int termkey = 0; int termkey = 0;
if (curbuf->b_term->tl_terminal_mode != 0)
{
/* Got back from TMODE_ONCE, enter Terminal-Job mode. */
term_leave_terminal_mode();
update_cursor(curbuf->b_term, TRUE);
}
if (*curwin->w_p_tk != NUL) if (*curwin->w_p_tk != NUL)
termkey = string_to_key(curwin->w_p_tk, TRUE); termkey = string_to_key(curwin->w_p_tk, TRUE);
position_cursor(curwin, &curbuf->b_term->tl_cursor_pos); position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
@@ -1097,7 +1086,7 @@ terminal_loop(void)
update_cursor(curbuf->b_term, FALSE); update_cursor(curbuf->b_term, FALSE);
c = term_vgetc(); c = term_vgetc();
if (!term_use_loop(FALSE)) if (!term_use_loop())
/* job finished while waiting for a character */ /* job finished while waiting for a character */
break; break;
@@ -1124,7 +1113,7 @@ terminal_loop(void)
#ifdef FEAT_CMDL_INFO #ifdef FEAT_CMDL_INFO
clear_showcmd(); clear_showcmd();
#endif #endif
if (!term_use_loop(FALSE)) if (!term_use_loop())
/* job finished while waiting for a character */ /* job finished while waiting for a character */
break; break;
@@ -1132,9 +1121,9 @@ terminal_loop(void)
{ {
if (c == Ctrl_N) if (c == Ctrl_N)
{ {
/* CTRL-\ CTRL-N : execute one Normal mode command. */ /* CTRL-\ CTRL-N : go to Terminal-Normal mode. */
term_enter_terminal_mode(TMODE_ONCE); term_enter_normal_mode();
return OK; return FAIL;
} }
/* Send both keys to the terminal. */ /* Send both keys to the terminal. */
send_keys_to_term(curbuf->b_term, prev_c, TRUE); send_keys_to_term(curbuf->b_term, prev_c, TRUE);
@@ -1146,7 +1135,8 @@ terminal_loop(void)
} }
else if (c == 'N') else if (c == 'N')
{ {
term_enter_terminal_mode(TMODE_LOOP); /* CTRL-W N : go to Terminal-Normal mode. */
term_enter_normal_mode();
return FAIL; return FAIL;
} }
else if (c == '"') else if (c == '"')
@@ -1249,7 +1239,7 @@ handle_movecursor(
if (wp->w_buffer == term->tl_buffer) if (wp->w_buffer == term->tl_buffer)
position_cursor(wp, &pos); position_cursor(wp, &pos);
} }
if (term->tl_buffer == curbuf && term->tl_terminal_mode == 0) if (term->tl_buffer == curbuf && !term->tl_normal_mode)
{ {
may_toggle_cursor(term); may_toggle_cursor(term);
update_cursor(term, term->tl_cursor_visible); update_cursor(term, term->tl_cursor_visible);
@@ -1385,7 +1375,7 @@ term_channel_closed(channel_T *ch)
term->tl_status_text = NULL; term->tl_status_text = NULL;
/* Unless in Terminal-Normal mode: clear the vterm. */ /* Unless in Terminal-Normal mode: clear the vterm. */
if (term->tl_terminal_mode == 0) if (!term->tl_normal_mode)
cleanup_vterm(term); cleanup_vterm(term);
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
@@ -1573,8 +1563,9 @@ cell2attr(VTermScreenCell *cell)
} }
/* /*
* Called to update the window that contains a terminal. * Called to update a window that contains an active terminal.
* Returns FAIL when there is no terminal running in this window. * Returns FAIL when there is no terminal running in this window or in
* Terminal-Normal mode.
*/ */
int int
term_update_window(win_T *wp) term_update_window(win_T *wp)
@@ -1585,7 +1576,7 @@ term_update_window(win_T *wp)
VTermState *state; VTermState *state;
VTermPos pos; VTermPos pos;
if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode != 0) if (term == NULL || term->tl_vterm == NULL || term->tl_normal_mode)
return FAIL; return FAIL;
vterm = term->tl_vterm; vterm = term->tl_vterm;
@@ -1707,15 +1698,14 @@ term_is_finished(buf_T *buf)
/* /*
* Return TRUE if "wp" is a terminal window where the job has finished or we * Return TRUE if "wp" is a terminal window where the job has finished or we
* are in Terminal-Normal mode. * are in Terminal-Normal mode, thus we show the buffer contents.
*/ */
int int
term_show_buffer(buf_T *buf) term_show_buffer(buf_T *buf)
{ {
term_T *term = buf->b_term; term_T *term = buf->b_term;
return term != NULL return term != NULL && (term->tl_vterm == NULL || term->tl_normal_mode);
&& (term->tl_vterm == NULL || term->tl_terminal_mode != 0);
} }
/* /*
@@ -1798,7 +1788,7 @@ term_get_status_text(term_T *term)
char_u *txt; char_u *txt;
size_t len; size_t len;
if (term->tl_terminal_mode != 0) if (term->tl_normal_mode)
{ {
if (term_job_running(term)) if (term_job_running(term))
txt = (char_u *)_("Terminal"); txt = (char_u *)_("Terminal");
@@ -2025,8 +2015,8 @@ f_term_getstatus(typval_T *argvars, typval_T *rettv)
STRCPY(val, "running"); STRCPY(val, "running");
else else
STRCPY(val, "finished"); STRCPY(val, "finished");
if (term->tl_terminal_mode != 0) if (term->tl_normal_mode)
STRCAT(val, ",terminal"); STRCAT(val, ",normal");
rettv->vval.v_string = vim_strsave(val); rettv->vval.v_string = vim_strsave(val);
} }
@@ -2187,7 +2177,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
msg += MB_PTR2LEN(msg); msg += MB_PTR2LEN(msg);
} }
if (term->tl_terminal_mode == 0) if (!term->tl_normal_mode)
{ {
/* TODO: only update once in a while. */ /* TODO: only update once in a while. */
update_screen(0); update_screen(0);

View File

@@ -769,6 +769,8 @@ 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 */
/**/
877,
/**/ /**/
876, 876,
/**/ /**/