Permalink
Browse files

patch 8.0.0813: cannot use a terminal window while the job is running

Problem:    Cannot use Vim commands in a terminal window while the job is
            running.
Solution:   Implement Terminal Normal mode.
  • Loading branch information...
brammool committed Jul 30, 2017
1 parent 68c4bdd commit 423802d1a282df35078539970eabf559186e1ec8
Showing with 351 additions and 137 deletions.
  1. +40 −6 runtime/doc/terminal.txt
  2. +10 −4 src/main.c
  3. +8 −0 src/normal.c
  4. +11 −1 src/option.c
  5. +5 −1 src/proto/terminal.pro
  6. +1 −1 src/screen.c
  7. +274 −124 src/terminal.c
  8. +2 −0 src/version.c
View
@@ -1,4 +1,4 @@
*terminal.txt* For Vim version 8.0. Last change: 2017 Jul 28
*terminal.txt* For Vim version 8.0. Last change: 2017 Jul 30
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -33,24 +33,39 @@ Or to run a debugger: >
The job runs asynchronously from Vim, the window will be updated to show
output from the job, also while editing in any other window.
Typing ~
When the keyboard focus is in the terminal window, typed keys will be send to
the job. This uses a pty when possible. You can click outside of the
terminal window to move keyboard focus elsewhere.
Navigate between windows with CTRL-W commands. E.g. CTRL-W CTRL-W moves focus
to the next window. Use "CTRL-W :" to edit an Ex command. Use "CTRL-W ." to
send a CTRL-W to the job in the terminal.
CTRL-W can be used to navigate between windows and other CTRL-W commands, e.g.:
CTRL-W CTRL-W move focus to the next window
CTRL-W : enter an Ex command
See |CTRL-W| for more commands.
Special in the terminal window: *CTRL-W_.* *CTRL-W_N*
CTRL-W . send a CTRL-W to the job in the terminal
CTRL-W N go to Terminal Normal mode, see |Terminal-mode|
See option 'termkey' for specifying another key instead of CTRL-W that
will work like CTRL-W. However, typing 'termkey' twice sends 'termkey' to
the job. For example:
'termkey' CTRL-W move focus to the next window
'termkey' : enter an Ex command
'termkey' 'termkey' send 'termkey' to the job in the terminal
'termkey' . send a CTRL-W to the job in the terminal
'termkey' N go to terminal Normal mode, see below
'termkey' CTRL-N same as CTRL-W N
See option 'termkey' for specifying another key that precedes a Vim command.
Typing 'termkey' twice sends 'termkey' to the job.
Size ~
See option 'termsize' for controlling the size of the terminal window.
(TODO: scrolling when the terminal is larger than the window)
Syntax ~
:ter[minal] [command] *:ter* *:terminal*
@@ -99,6 +114,25 @@ terminal. |term_setsize()| can be used only when in the first or second mode,
not when 'termsize' is "rowsXcols".
Terminal Normal mode ~
*Terminal-mode*
When the job is running the contents of the terminal is under control of the
job. That includes the cursor position. The terminal contents can change at
any time.
Use CTRL-W N (or 'termkey' N) to go to Terminal Normal mode. Now the contents
of the terminal window is under control of Vim, the job output is suspended.
*E946*
In this mode you can move the cursor around with the usual Vim commands,
Visually mark text, yank text, etc. But you cannot change the contents of the
buffer. The commands that would start insert mode, such as 'i' and 'a',
return control of the window to the job. Any pending output will now be
displayed.
In Terminal mode the statusline and window title show "(Terminal)". If the
job ends while in Terminal mode this changes to "(Terminal-finished)".
Unix ~
On Unix a pty is used to make it possible to run all kinds of commands. You
View
@@ -1356,11 +1356,17 @@ main_loop(
else
{
#ifdef FEAT_TERMINAL
if (curbuf->b_term != NULL && oa.op_type == OP_NOP
&& oa.regname == NUL)
terminal_loop();
if (term_use_loop() && oa.op_type == OP_NOP && oa.regname == NUL)
{
/* If terminal_loop() returns OK we got a key that is handled
* in Normal model. With FAIL the terminal was closed and the
* screen needs to be redrawn. */
if (terminal_loop() == OK)
normal_cmd(&oa, TRUE);
}
else
#endif
normal_cmd(&oa, TRUE);
normal_cmd(&oa, TRUE);
}
}
}
View
@@ -9037,6 +9037,14 @@ nv_esc(cmdarg_T *cap)
static void
nv_edit(cmdarg_T *cap)
{
#ifdef FEAT_TERMINAL
if (term_in_terminal_mode())
{
term_leave_terminal_mode();
return;
}
#endif
/* <Insert> is equal to "i" */
if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS)
cap->cmdchar = 'i';
View
@@ -8222,12 +8222,22 @@ set_bool_option(
}
#endif
#ifdef FEAT_TITLE
/* when 'modifiable' is changed, redraw the window title */
else if ((int *)varp == &curbuf->b_p_ma)
{
# ifdef FEAT_TERMINAL
/* Cannot set 'modifiable' when in Terminal mode. */
if (term_in_terminal_mode())
{
curbuf->b_p_ma = FALSE;
return (char_u *)N_("E946: Cannot make a terminal with running job modifiable");
}
# endif
# ifdef FEAT_TITLE
redraw_titles();
# endif
}
#ifdef FEAT_TITLE
/* when 'endofline' is changed, redraw the window title */
else if ((int *)varp == &curbuf->b_p_eol)
{
View
@@ -2,11 +2,15 @@
void ex_terminal(exarg_T *eap);
void free_terminal(buf_T *buf);
void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
int term_in_terminal_mode(void);
void term_leave_terminal_mode(void);
int term_use_loop(void);
int terminal_loop(void);
void term_job_ended(job_T *job);
void term_channel_closed(channel_T *ch);
int term_update_window(win_T *wp);
int term_is_finished(buf_T *buf);
int term_show_buffer(buf_T *buf);
void term_change_in_curbuf(void);
int term_get_attr(buf_T *buf, linenr_T lnum, int col);
char_u *term_get_status_text(term_T *term);
@@ -16,8 +20,8 @@ void f_term_getjob(typval_T *argvars, typval_T *rettv);
void f_term_getline(typval_T *argvars, typval_T *rettv);
void f_term_getsize(typval_T *argvars, typval_T *rettv);
void f_term_list(typval_T *argvars, typval_T *rettv);
void f_term_start(typval_T *argvars, typval_T *rettv);
void f_term_scrape(typval_T *argvars, typval_T *rettv);
void f_term_sendkeys(typval_T *argvars, typval_T *rettv);
void f_term_start(typval_T *argvars, typval_T *rettv);
void f_term_wait(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
View
@@ -3245,7 +3245,7 @@ win_line(
#endif
#ifdef FEAT_TERMINAL
if (term_is_finished(wp->w_buffer))
if (term_show_buffer(wp->w_buffer))
{
extra_check = TRUE;
get_term_attr = TRUE;
Oops, something went wrong.

0 comments on commit 423802d

Please sign in to comment.