Skip to content

Commit aaa8a35

Browse files
committed
patch 8.0.0873: in terminal cannot use CTRL-\ CTRL-N to start Visual mode
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.
1 parent 98fd66d commit aaa8a35

File tree

4 files changed

+58
-26
lines changed

4 files changed

+58
-26
lines changed

src/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,9 @@ main_loop(
13561356
else
13571357
{
13581358
#ifdef FEAT_TERMINAL
1359-
if (term_use_loop() && oa.op_type == OP_NOP && oa.regname == NUL)
1359+
if (term_use_loop(TRUE)
1360+
&& oa.op_type == OP_NOP && oa.regname == NUL
1361+
&& !VIsual_active)
13601362
{
13611363
/* If terminal_loop() returns OK we got a key that is handled
13621364
* in Normal model. With FAIL the terminal was closed and the

src/proto/terminal.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int term_job_running(term_T *term);
66
int term_in_terminal_mode(void);
77
void term_leave_terminal_mode(void);
88
int send_keys_to_term(term_T *term, int c, int typed);
9-
int term_use_loop(void);
9+
int term_use_loop(int once);
1010
int terminal_loop(void);
1111
void term_job_ended(job_T *job);
1212
void term_channel_closed(channel_T *ch);

src/terminal.c

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ struct terminal_S {
115115
int tl_tty_fd;
116116
char_u *tl_tty_name;
117117

118-
int tl_terminal_mode;
118+
int tl_terminal_mode; /* 0, TMODE_ONCE or TMODE_LOOP */
119119
int tl_channel_closed;
120120

121121
#ifdef WIN3264
@@ -144,6 +144,9 @@ struct terminal_S {
144144
int tl_cursor_visible;
145145
};
146146

147+
#define TMODE_ONCE 1 /* CTRL-\ CTRL-N used */
148+
#define TMODE_LOOP 2 /* CTRL-W N used */
149+
147150
/*
148151
* List of all active terminals.
149152
*/
@@ -459,7 +462,7 @@ term_write_job_output(term_T *term, char_u *msg, size_t len)
459462
static void
460463
update_cursor(term_T *term, int redraw)
461464
{
462-
if (term->tl_terminal_mode)
465+
if (term->tl_terminal_mode != 0)
463466
return;
464467
setcursor();
465468
if (redraw && term->tl_buffer == curbuf)
@@ -492,7 +495,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
492495
ch_log(channel, "writing %d bytes to terminal", (int)len);
493496
term_write_job_output(term, msg, len);
494497

495-
if (!term->tl_terminal_mode)
498+
if (term->tl_terminal_mode == 0)
496499
{
497500
/* TODO: only update once in a while. */
498501
update_screen(0);
@@ -805,9 +808,9 @@ move_terminal_to_buffer(term_T *term)
805808
}
806809

807810
static void
808-
set_terminal_mode(term_T *term, int on)
811+
set_terminal_mode(term_T *term, int mode)
809812
{
810-
term->tl_terminal_mode = on;
813+
term->tl_terminal_mode = mode;
811814
vim_free(term->tl_status_text);
812815
term->tl_status_text = NULL;
813816
if (term->tl_buffer == curbuf)
@@ -823,22 +826,35 @@ cleanup_vterm(term_T *term)
823826
{
824827
move_terminal_to_buffer(term);
825828
term_free_vterm(term);
826-
set_terminal_mode(term, FALSE);
829+
set_terminal_mode(term, 0);
827830
}
828831

829832
/*
830-
* Switch from sending keys to the job to Terminal-Normal mode.
833+
* Switch from Terminal-Job mode to Terminal-Normal mode.
831834
* Suspends updating the terminal window.
832835
*/
833836
static void
834-
term_enter_terminal_mode()
837+
term_enter_terminal_mode(int mode)
835838
{
836839
term_T *term = curbuf->b_term;
837840

838841
/* Append the current terminal contents to the buffer. */
839842
move_terminal_to_buffer(term);
840843

841-
set_terminal_mode(term, TRUE);
844+
set_terminal_mode(term, mode);
845+
846+
if (mode == TMODE_ONCE)
847+
{
848+
/* Move the window cursor to the position of the cursor in the
849+
* terminal. */
850+
curwin->w_cursor.lnum = term->tl_scrollback_scrolled
851+
+ term->tl_cursor_pos.row + 1;
852+
check_cursor();
853+
coladvance(term->tl_cursor_pos.col);
854+
855+
/* Display the same lines as in the terminal. */
856+
curwin->w_topline = term->tl_scrollback_scrolled + 1;
857+
}
842858
}
843859

844860
/*
@@ -850,11 +866,11 @@ term_in_terminal_mode()
850866
{
851867
term_T *term = curbuf->b_term;
852868

853-
return term != NULL && term->tl_terminal_mode;
869+
return term != NULL && term->tl_terminal_mode != 0;
854870
}
855871

856872
/*
857-
* Switch from Terminal-Normal mode to sending keys to the job.
873+
* Switch from Terminal-Normal mode to Terminal-Job mode.
858874
* Restores updating the terminal window.
859875
*/
860876
void
@@ -877,7 +893,7 @@ term_leave_terminal_mode()
877893
}
878894
check_cursor();
879895

880-
set_terminal_mode(term, FALSE);
896+
set_terminal_mode(term, 0);
881897

882898
if (term->tl_channel_closed)
883899
cleanup_vterm(term);
@@ -1037,12 +1053,13 @@ term_paste_register(int prev_c UNUSED)
10371053
* keys to the job.
10381054
*/
10391055
int
1040-
term_use_loop()
1056+
term_use_loop(int once)
10411057
{
10421058
term_T *term = curbuf->b_term;
10431059

10441060
return term != NULL
1045-
&& !term->tl_terminal_mode
1061+
&& (once ? term->tl_terminal_mode != TMODE_LOOP
1062+
: term->tl_terminal_mode == 0)
10461063
&& term->tl_vterm != NULL
10471064
&& term_job_running(term);
10481065
}
@@ -1060,6 +1077,13 @@ terminal_loop(void)
10601077
int c;
10611078
int termkey = 0;
10621079

1080+
if (curbuf->b_term->tl_terminal_mode != 0)
1081+
{
1082+
/* Got back from TMODE_ONCE, enter Terminal-Job mode. */
1083+
term_leave_terminal_mode();
1084+
update_cursor(curbuf->b_term, TRUE);
1085+
}
1086+
10631087
if (*curwin->w_p_tk != NUL)
10641088
termkey = string_to_key(curwin->w_p_tk, TRUE);
10651089
position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
@@ -1073,7 +1097,7 @@ terminal_loop(void)
10731097
update_cursor(curbuf->b_term, FALSE);
10741098

10751099
c = term_vgetc();
1076-
if (!term_use_loop())
1100+
if (!term_use_loop(FALSE))
10771101
/* job finished while waiting for a character */
10781102
break;
10791103

@@ -1100,15 +1124,18 @@ terminal_loop(void)
11001124
#ifdef FEAT_CMDL_INFO
11011125
clear_showcmd();
11021126
#endif
1103-
if (!term_use_loop())
1127+
if (!term_use_loop(FALSE))
11041128
/* job finished while waiting for a character */
11051129
break;
11061130

11071131
if (prev_c == Ctrl_BSL)
11081132
{
11091133
if (c == Ctrl_N)
1134+
{
11101135
/* CTRL-\ CTRL-N : execute one Normal mode command. */
1136+
term_enter_terminal_mode(TMODE_ONCE);
11111137
return OK;
1138+
}
11121139
/* Send both keys to the terminal. */
11131140
send_keys_to_term(curbuf->b_term, prev_c, TRUE);
11141141
}
@@ -1119,7 +1146,7 @@ terminal_loop(void)
11191146
}
11201147
else if (c == 'N')
11211148
{
1122-
term_enter_terminal_mode();
1149+
term_enter_terminal_mode(TMODE_LOOP);
11231150
return FAIL;
11241151
}
11251152
else if (c == '"')
@@ -1222,7 +1249,7 @@ handle_movecursor(
12221249
if (wp->w_buffer == term->tl_buffer)
12231250
position_cursor(wp, &pos);
12241251
}
1225-
if (term->tl_buffer == curbuf && !term->tl_terminal_mode)
1252+
if (term->tl_buffer == curbuf && term->tl_terminal_mode == 0)
12261253
{
12271254
may_toggle_cursor(term);
12281255
update_cursor(term, term->tl_cursor_visible);
@@ -1358,7 +1385,7 @@ term_channel_closed(channel_T *ch)
13581385
term->tl_status_text = NULL;
13591386

13601387
/* Unless in Terminal-Normal mode: clear the vterm. */
1361-
if (!term->tl_terminal_mode)
1388+
if (term->tl_terminal_mode == 0)
13621389
cleanup_vterm(term);
13631390

13641391
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
@@ -1558,7 +1585,7 @@ term_update_window(win_T *wp)
15581585
VTermState *state;
15591586
VTermPos pos;
15601587

1561-
if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode)
1588+
if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode != 0)
15621589
return FAIL;
15631590

15641591
vterm = term->tl_vterm;
@@ -1687,7 +1714,8 @@ term_show_buffer(buf_T *buf)
16871714
{
16881715
term_T *term = buf->b_term;
16891716

1690-
return term != NULL && (term->tl_vterm == NULL || term->tl_terminal_mode);
1717+
return term != NULL
1718+
&& (term->tl_vterm == NULL || term->tl_terminal_mode != 0);
16911719
}
16921720

16931721
/*
@@ -1770,7 +1798,7 @@ term_get_status_text(term_T *term)
17701798
char_u *txt;
17711799
size_t len;
17721800

1773-
if (term->tl_terminal_mode)
1801+
if (term->tl_terminal_mode != 0)
17741802
{
17751803
if (term_job_running(term))
17761804
txt = (char_u *)_("Terminal");
@@ -1997,7 +2025,7 @@ f_term_getstatus(typval_T *argvars, typval_T *rettv)
19972025
STRCPY(val, "running");
19982026
else
19992027
STRCPY(val, "finished");
2000-
if (term->tl_terminal_mode)
2028+
if (term->tl_terminal_mode != 0)
20012029
STRCAT(val, ",terminal");
20022030
rettv->vval.v_string = vim_strsave(val);
20032031
}
@@ -2159,7 +2187,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
21592187
msg += MB_PTR2LEN(msg);
21602188
}
21612189

2162-
if (!term->tl_terminal_mode)
2190+
if (term->tl_terminal_mode == 0)
21632191
{
21642192
/* TODO: only update once in a while. */
21652193
update_screen(0);

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
873,
772774
/**/
773775
872,
774776
/**/

0 commit comments

Comments
 (0)