summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-05 20:17:00 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-05 20:17:00 +0200
commitaaa8a35fbd38d5e6cc57ae60a8477e787d695a20 (patch)
tree43e7eea1c383b19077c3449e297b8a383a84f2fd
parent98fd66d311a62133c835307dc7692763dfa32c69 (diff)
patch 8.0.0873: in terminal cannot use CTRL-\ CTRL-N to start Visual modev8.0.0873
Problem: In a terminal window cannot use CTRL-\ CTRL-N to start Visual mode. Solution: After CTRL-\ CTRL-N enter Terminal-Normal mode for one command.
-rw-r--r--src/main.c4
-rw-r--r--src/proto/terminal.pro2
-rw-r--r--src/terminal.c76
-rw-r--r--src/version.c2
4 files changed, 58 insertions, 26 deletions
diff --git a/src/main.c b/src/main.c
index 81eb1a6799..615858bcc0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1356,7 +1356,9 @@ main_loop(
else
{
#ifdef FEAT_TERMINAL
- if (term_use_loop() && oa.op_type == OP_NOP && oa.regname == NUL)
+ if (term_use_loop(TRUE)
+ && oa.op_type == OP_NOP && oa.regname == NUL
+ && !VIsual_active)
{
/* If terminal_loop() returns OK we got a key that is handled
* in Normal model. With FAIL the terminal was closed and the
diff --git a/src/proto/terminal.pro b/src/proto/terminal.pro
index b6c27ed0b6..fbd17eddee 100644
--- a/src/proto/terminal.pro
+++ b/src/proto/terminal.pro
@@ -6,7 +6,7 @@ int term_job_running(term_T *term);
int term_in_terminal_mode(void);
void term_leave_terminal_mode(void);
int send_keys_to_term(term_T *term, int c, int typed);
-int term_use_loop(void);
+int term_use_loop(int once);
int terminal_loop(void);
void term_job_ended(job_T *job);
void term_channel_closed(channel_T *ch);
diff --git a/src/terminal.c b/src/terminal.c
index 20c927248a..7d26deb142 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -115,7 +115,7 @@ struct terminal_S {
int tl_tty_fd;
char_u *tl_tty_name;
- int tl_terminal_mode;
+ int tl_terminal_mode; /* 0, TMODE_ONCE or TMODE_LOOP */
int tl_channel_closed;
#ifdef WIN3264
@@ -144,6 +144,9 @@ struct terminal_S {
int tl_cursor_visible;
};
+#define TMODE_ONCE 1 /* CTRL-\ CTRL-N used */
+#define TMODE_LOOP 2 /* CTRL-W N used */
+
/*
* List of all active terminals.
*/
@@ -459,7 +462,7 @@ term_write_job_output(term_T *term, char_u *msg, size_t len)
static void
update_cursor(term_T *term, int redraw)
{
- if (term->tl_terminal_mode)
+ if (term->tl_terminal_mode != 0)
return;
setcursor();
if (redraw && term->tl_buffer == curbuf)
@@ -492,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);
term_write_job_output(term, msg, len);
- if (!term->tl_terminal_mode)
+ if (term->tl_terminal_mode == 0)
{
/* TODO: only update once in a while. */
update_screen(0);
@@ -805,9 +808,9 @@ move_terminal_to_buffer(term_T *term)
}
static void
-set_terminal_mode(term_T *term, int on)
+set_terminal_mode(term_T *term, int mode)
{
- term->tl_terminal_mode = on;
+ term->tl_terminal_mode = mode;
vim_free(term->tl_status_text);
term->tl_status_text = NULL;
if (term->tl_buffer == curbuf)
@@ -823,22 +826,35 @@ cleanup_vterm(term_T *term)
{
move_terminal_to_buffer(term);
term_free_vterm(term);
- set_terminal_mode(term, FALSE);
+ set_terminal_mode(term, 0);
}
/*
- * Switch from sending keys to the job to Terminal-Normal mode.
+ * Switch from Terminal-Job mode to Terminal-Normal mode.
* Suspends updating the terminal window.
*/
static void
-term_enter_terminal_mode()
+term_enter_terminal_mode(int mode)
{
term_T *term = curbuf->b_term;
/* Append the current terminal contents to the buffer. */
move_terminal_to_buffer(term);
- set_terminal_mode(term, TRUE);
+ set_terminal_mode(term, mode);
+
+ if (mode == TMODE_ONCE)
+ {
+ /* Move the window cursor to the position of the cursor in the
+ * terminal. */
+ curwin->w_cursor.lnum = term->tl_scrollback_scrolled
+ + term->tl_cursor_pos.row + 1;
+ check_cursor();
+ coladvance(term->tl_cursor_pos.col);
+
+ /* Display the same lines as in the terminal. */
+ curwin->w_topline = term->tl_scrollback_scrolled + 1;
+ }
}
/*
@@ -850,11 +866,11 @@ term_in_terminal_mode()
{
term_T *term = curbuf->b_term;
- return term != NULL && term->tl_terminal_mode;
+ return term != NULL && term->tl_terminal_mode != 0;
}
/*
- * Switch from Terminal-Normal mode to sending keys to the job.
+ * Switch from Terminal-Normal mode to Terminal-Job mode.
* Restores updating the terminal window.
*/
void
@@ -877,7 +893,7 @@ term_leave_terminal_mode()
}
check_cursor();
- set_terminal_mode(term, FALSE);
+ set_terminal_mode(term, 0);
if (term->tl_channel_closed)
cleanup_vterm(term);
@@ -1037,12 +1053,13 @@ term_paste_register(int prev_c UNUSED)
* keys to the job.
*/
int
-term_use_loop()
+term_use_loop(int once)
{
term_T *term = curbuf->b_term;
return term != NULL
- && !term->tl_terminal_mode
+ && (once ? term->tl_terminal_mode != TMODE_LOOP
+ : term->tl_terminal_mode == 0)
&& term->tl_vterm != NULL
&& term_job_running(term);
}
@@ -1060,6 +1077,13 @@ terminal_loop(void)
int c;
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)
termkey = string_to_key(curwin->w_p_tk, TRUE);
position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
@@ -1073,7 +1097,7 @@ terminal_loop(void)
update_cursor(curbuf->b_term, FALSE);
c = term_vgetc();
- if (!term_use_loop())
+ if (!term_use_loop(FALSE))
/* job finished while waiting for a character */
break;
@@ -1100,15 +1124,18 @@ terminal_loop(void)
#ifdef FEAT_CMDL_INFO
clear_showcmd();
#endif
- if (!term_use_loop())
+ if (!term_use_loop(FALSE))
/* job finished while waiting for a character */
break;
if (prev_c == Ctrl_BSL)
{
if (c == Ctrl_N)
+ {
/* CTRL-\ CTRL-N : execute one Normal mode command. */
+ term_enter_terminal_mode(TMODE_ONCE);
return OK;
+ }
/* Send both keys to the terminal. */
send_keys_to_term(curbuf->b_term, prev_c, TRUE);
}
@@ -1119,7 +1146,7 @@ terminal_loop(void)
}
else if (c == 'N')
{
- term_enter_terminal_mode();
+ term_enter_terminal_mode(TMODE_LOOP);
return FAIL;
}
else if (c == '"')
@@ -1222,7 +1249,7 @@ handle_movecursor(
if (wp->w_buffer == term->tl_buffer)
position_cursor(wp, &pos);
}
- if (term->tl_buffer == curbuf && !term->tl_terminal_mode)
+ if (term->tl_buffer == curbuf && term->tl_terminal_mode == 0)
{
may_toggle_cursor(term);
update_cursor(term, term->tl_cursor_visible);
@@ -1358,7 +1385,7 @@ term_channel_closed(channel_T *ch)
term->tl_status_text = NULL;
/* Unless in Terminal-Normal mode: clear the vterm. */
- if (!term->tl_terminal_mode)
+ if (term->tl_terminal_mode == 0)
cleanup_vterm(term);
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
@@ -1558,7 +1585,7 @@ term_update_window(win_T *wp)
VTermState *state;
VTermPos pos;
- if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode)
+ if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode != 0)
return FAIL;
vterm = term->tl_vterm;
@@ -1687,7 +1714,8 @@ term_show_buffer(buf_T *buf)
{
term_T *term = buf->b_term;
- return term != NULL && (term->tl_vterm == NULL || term->tl_terminal_mode);
+ return term != NULL
+ && (term->tl_vterm == NULL || term->tl_terminal_mode != 0);
}
/*
@@ -1770,7 +1798,7 @@ term_get_status_text(term_T *term)
char_u *txt;
size_t len;
- if (term->tl_terminal_mode)
+ if (term->tl_terminal_mode != 0)
{
if (term_job_running(term))
txt = (char_u *)_("Terminal");
@@ -1997,7 +2025,7 @@ f_term_getstatus(typval_T *argvars, typval_T *rettv)
STRCPY(val, "running");
else
STRCPY(val, "finished");
- if (term->tl_terminal_mode)
+ if (term->tl_terminal_mode != 0)
STRCAT(val, ",terminal");
rettv->vval.v_string = vim_strsave(val);
}
@@ -2159,7 +2187,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
msg += MB_PTR2LEN(msg);
}
- if (!term->tl_terminal_mode)
+ if (term->tl_terminal_mode == 0)
{
/* TODO: only update once in a while. */
update_screen(0);
diff --git a/src/version.c b/src/version.c
index b3f3eb5253..54acc59d33 100644
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 873,
+/**/
872,
/**/
871,