Patch 8.0.0718
Problem: Output of job in terminal is not displayed.
Solution: Connect the job output to the terminal.
Files: src/channel.c, src/proto/channel.pro, src/terminal.c,
src/proto/terminal.pro, src/channel.c, src/proto/channel.pro,
src/evalfunc.c, src/screen.c, src/proto/screen.pro
*** ../vim-8.0.0717/src/channel.c 2017-07-15 17:01:50.350726204 +0200
--- src/channel.c 2017-07-15 22:18:35.029671290 +0200
***************
*** 171,177 ****
}
}
! static void
ch_logn(channel_T *ch, char *msg, int nr)
{
if (log_fd != NULL)
--- 171,177 ----
}
}
! void
ch_logn(channel_T *ch, char *msg, int nr)
{
if (log_fd != NULL)
***************
*** 2656,2662 ****
/* JSON or JS mode: re-encode the message. */
msg = json_encode(listtv, ch_mode);
if (msg != NULL)
! append_to_buffer(buffer, msg, channel, part);
}
if (callback != NULL)
--- 2656,2667 ----
/* JSON or JS mode: re-encode the message. */
msg = json_encode(listtv, ch_mode);
if (msg != NULL)
! {
! if (buffer->b_term != NULL)
! write_to_term(buffer, msg, channel);
! else
! append_to_buffer(buffer, msg, channel, part);
! }
}
if (callback != NULL)
***************
*** 4889,4895 ****
* "job_start()" function
*/
job_T *
! job_start(typval_T *argvars)
{
job_T *job;
char_u *cmd = NULL;
--- 4894,4900 ----
* "job_start()" function
*/
job_T *
! job_start(typval_T *argvars, jobopt_T *opt_arg)
{
job_T *job;
char_u *cmd = NULL;
***************
*** 4912,4924 ****
ga_init2(&ga, (int)sizeof(char*), 20);
#endif
! /* Default mode is NL. */
! clear_job_options(&opt);
! opt.jo_mode = MODE_NL;
! if (get_job_options(&argvars[1], &opt,
JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
goto theend;
/* Check that when io is "file" that there is a file name. */
for (part = PART_OUT; part < PART_COUNT; ++part)
--- 4917,4934 ----
ga_init2(&ga, (int)sizeof(char*), 20);
#endif
! if (opt_arg != NULL)
! opt = *opt_arg;
! else
! {
! /* Default mode is NL. */
! clear_job_options(&opt);
! opt.jo_mode = MODE_NL;
! if (get_job_options(&argvars[1], &opt,
JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
goto theend;
+ }
/* Check that when io is "file" that there is a file name. */
for (part = PART_OUT; part < PART_COUNT; ++part)
*** ../vim-8.0.0717/src/proto/channel.pro 2016-12-01 15:34:04.087413921
+0100
--- src/proto/channel.pro 2017-07-15 20:41:05.457918326 +0200
***************
*** 2,7 ****
--- 2,8 ----
void ch_logfile(char_u *fname, char_u *opt);
int ch_log_active(void);
void ch_log(channel_T *ch, char *msg);
+ void ch_logn(channel_T *ch, char *msg, int nr);
void ch_logs(channel_T *ch, char *msg, char *name);
channel_T *add_channel(void);
int has_any_channel(void);
***************
*** 63,69 ****
void job_stop_on_exit(void);
int has_pending_job(void);
void job_check_ended(void);
! job_T *job_start(typval_T *argvars);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
int job_stop(job_T *job, typval_T *argvars);
--- 64,70 ----
void job_stop_on_exit(void);
int has_pending_job(void);
void job_check_ended(void);
! job_T *job_start(typval_T *argvars, jobopt_T *opt_arg);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
int job_stop(job_T *job, typval_T *argvars);
*** ../vim-8.0.0717/src/terminal.c 2017-07-15 20:05:50.802053721 +0200
--- src/terminal.c 2017-07-15 22:53:26.785858885 +0200
***************
*** 28,33 ****
--- 28,35 ----
* - remove term from first_term list when closing terminal.
* - set buffer options to be scratch, hidden, nomodifiable, etc.
* - set buffer name to command, add (1) to avoid duplicates.
+ * - if buffer is wiped, cleanup terminal, may stop job.
+ * - if the job ends, write "-- JOB ENDED --" in the terminal
* - command line completion (command name)
* - support fixed size when 'termsize' is "rowsXcols".
* - support minimal size when 'termsize' is "rows*cols".
***************
*** 40,45 ****
--- 42,48 ----
* - implement term_scrape() inspect terminal screen
* - implement term_open() open terminal window
* - implement term_getjob()
+ * - implement 'termkey'
*/
#include "vim.h"
***************
*** 54,59 ****
--- 57,63 ----
VTerm *tl_vterm;
job_T *tl_job;
+ buf_T *tl_buffer;
/* Range of screen rows to update. Zero based. */
int tl_dirty_row_start; /* -1 if nothing dirty */
***************
*** 99,104 ****
--- 103,109 ----
term_T *term;
VTerm *vterm;
VTermScreen *screen;
+ jobopt_T opt;
if (check_restricted() || check_secure())
return;
***************
*** 120,125 ****
--- 125,131 ----
vim_free(term);
return;
}
+ term->tl_buffer = curbuf;
curbuf->b_term = term;
term->tl_next = first_term;
***************
*** 145,160 ****
term->tl_vterm = vterm;
screen = vterm_obtain_screen(vterm);
vterm_screen_set_callbacks(screen, &screen_callbacks, term);
argvars[0].v_type = VAR_STRING;
argvars[0].vval.v_string = eap->arg;
- argvars[1].v_type = VAR_UNKNOWN;
- term->tl_job = job_start(argvars);
! /* TODO: setup channels to/from job */
/* Setup pty, see mch_call_shell(). */
}
static int
handle_damage(VTermRect rect, void *user)
{
--- 151,246 ----
term->tl_vterm = vterm;
screen = vterm_obtain_screen(vterm);
vterm_screen_set_callbacks(screen, &screen_callbacks, term);
+ /* TODO: depends on 'encoding'. */
+ vterm_set_utf8(vterm, 1);
+ /* Required to initialize most things. */
+ vterm_screen_reset(screen, 1 /* hard */);
+
+ /* By default NL means CR-NL. */
+ vterm_input_write(vterm, "\x1b[20h", 5);
argvars[0].v_type = VAR_STRING;
argvars[0].vval.v_string = eap->arg;
! clear_job_options(&opt);
! opt.jo_mode = MODE_RAW;
! opt.jo_out_mode = MODE_RAW;
! opt.jo_err_mode = MODE_RAW;
! opt.jo_set = JO_MODE | JO_OUT_MODE | JO_ERR_MODE;
! opt.jo_io[PART_OUT] = JIO_BUFFER;
! opt.jo_io[PART_ERR] = JIO_BUFFER;
! opt.jo_set |= JO_OUT_IO + (JO_OUT_IO << (PART_ERR - PART_OUT));
! opt.jo_io_buf[PART_OUT] = curbuf->b_fnum;
! opt.jo_io_buf[PART_ERR] = curbuf->b_fnum;
! opt.jo_set |= JO_OUT_BUF + (JO_OUT_BUF << (PART_ERR - PART_OUT));
!
! term->tl_job = job_start(argvars, &opt);
!
! /* TODO: setup channel to job */
/* Setup pty, see mch_call_shell(). */
}
+ /*
+ * Invoked when "msg" output from a job was received. Write it to the
terminal
+ * of "buffer".
+ */
+ void
+ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
+ {
+ size_t len = STRLEN(msg);
+ VTerm *vterm = buffer->b_term->tl_vterm;
+
+ ch_logn(channel, "writing %d bytes to terminal", (int)len);
+ vterm_input_write(vterm, (char *)msg, len);
+ vterm_screen_flush_damage(vterm_obtain_screen(vterm));
+
+ /* TODO: only update once in a while. */
+ update_screen(0);
+ setcursor();
+ out_flush();
+ }
+
+ /*
+ * Called to update the window that contains the terminal.
+ */
+ void
+ term_update_window(win_T *wp)
+ {
+ int vterm_rows;
+ int vterm_cols;
+ VTerm *vterm = wp->w_buffer->b_term->tl_vterm;
+ VTermScreen *screen = vterm_obtain_screen(vterm);
+ VTermPos pos;
+
+ vterm_get_size(vterm, &vterm_rows, &vterm_cols);
+
+ /* TODO: Only redraw what changed. */
+ for (pos.row = 0; pos.row < wp->w_height; ++pos.row)
+ {
+ int off = screen_get_current_line_off();
+
+ if (pos.row < vterm_rows)
+ for (pos.col = 0; pos.col < wp->w_width && pos.col < vterm_cols;
+ ++pos.col)
+ {
+ VTermScreenCell cell;
+ int c;
+
+ vterm_screen_get_cell(screen, pos, &cell);
+ /* TODO: use cell.attrs and colors */
+ /* TODO: use cell.width */
+ /* TODO: multi-byte chars */
+ c = cell.chars[0];
+ ScreenLines[off] = c == NUL ? ' ' : c;
+ ScreenAttrs[off] = 0;
+ ++off;
+ }
+
+ screen_line(wp->w_winrow + pos.row, wp->w_wincol, pos.col, wp->w_width,
+ FALSE);
+ }
+ }
+
static int
handle_damage(VTermRect rect, void *user)
{
***************
*** 162,188 ****
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);
return 1;
}
static int
handle_moverect(VTermRect dest, VTermRect src, void *user)
{
/* TODO */
return 1;
}
static int
handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
{
! /* TODO: handle moving the cursor. */
return 1;
}
static int
handle_resize(int rows, int cols, void *user)
{
/* TODO: handle terminal resize. */
return 1;
}
--- 248,302 ----
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);
+ redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
static int
handle_moverect(VTermRect dest, VTermRect src, void *user)
{
+ term_T *term = (term_T *)user;
+
/* TODO */
+ redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
static int
handle_movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user)
{
! term_T *term = (term_T *)user;
! win_T *wp;
! int is_current = FALSE;
!
! FOR_ALL_WINDOWS(wp)
! {
! if (wp->w_buffer == term->tl_buffer)
! {
! /* TODO: limit to window size? */
! wp->w_wrow = pos.row;
! wp->w_wcol = pos.col;
! if (wp == curwin)
! is_current = TRUE;
! }
! }
!
! if (is_current)
! {
! setcursor();
! out_flush();
! }
!
return 1;
}
static int
handle_resize(int rows, int cols, void *user)
{
+ term_T *term = (term_T *)user;
+
/* TODO: handle terminal resize. */
+ redraw_buf_later(term->tl_buffer, NOT_VALID);
return 1;
}
***************
*** 201,210 ****
* - Write output to channel.
*/
- /* TODO: function to read job output from the channel.
- * write to vterm: vterm_input_write()
- * This will invoke screen callbacks.
- * call vterm_screen_flush_damage()
- */
-
#endif /* FEAT_TERMINAL */
--- 315,318 ----
*** ../vim-8.0.0717/src/proto/terminal.pro 2017-07-07 11:53:29.515876528
+0200
--- src/proto/terminal.pro 2017-07-15 21:37:51.732076242 +0200
***************
*** 1,3 ****
--- 1,5 ----
/* terminal.c */
void ex_terminal(exarg_T *eap);
+ void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel);
+ void term_update_window(win_T *wp);
/* vim: set ft=c : */
*** ../vim-8.0.0717/src/channel.c 2017-07-15 17:01:50.350726204 +0200
--- src/channel.c 2017-07-15 22:18:35.029671290 +0200
***************
*** 171,177 ****
}
}
! static void
ch_logn(channel_T *ch, char *msg, int nr)
{
if (log_fd != NULL)
--- 171,177 ----
}
}
! void
ch_logn(channel_T *ch, char *msg, int nr)
{
if (log_fd != NULL)
***************
*** 2656,2662 ****
/* JSON or JS mode: re-encode the message. */
msg = json_encode(listtv, ch_mode);
if (msg != NULL)
! append_to_buffer(buffer, msg, channel, part);
}
if (callback != NULL)
--- 2656,2667 ----
/* JSON or JS mode: re-encode the message. */
msg = json_encode(listtv, ch_mode);
if (msg != NULL)
! {
! if (buffer->b_term != NULL)
! write_to_term(buffer, msg, channel);
! else
! append_to_buffer(buffer, msg, channel, part);
! }
}
if (callback != NULL)
***************
*** 4889,4895 ****
* "job_start()" function
*/
job_T *
! job_start(typval_T *argvars)
{
job_T *job;
char_u *cmd = NULL;
--- 4894,4900 ----
* "job_start()" function
*/
job_T *
! job_start(typval_T *argvars, jobopt_T *opt_arg)
{
job_T *job;
char_u *cmd = NULL;
***************
*** 4912,4924 ****
ga_init2(&ga, (int)sizeof(char*), 20);
#endif
! /* Default mode is NL. */
! clear_job_options(&opt);
! opt.jo_mode = MODE_NL;
! if (get_job_options(&argvars[1], &opt,
JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
goto theend;
/* Check that when io is "file" that there is a file name. */
for (part = PART_OUT; part < PART_COUNT; ++part)
--- 4917,4934 ----
ga_init2(&ga, (int)sizeof(char*), 20);
#endif
! if (opt_arg != NULL)
! opt = *opt_arg;
! else
! {
! /* Default mode is NL. */
! clear_job_options(&opt);
! opt.jo_mode = MODE_NL;
! if (get_job_options(&argvars[1], &opt,
JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
+ JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
goto theend;
+ }
/* Check that when io is "file" that there is a file name. */
for (part = PART_OUT; part < PART_COUNT; ++part)
*** ../vim-8.0.0717/src/proto/channel.pro 2016-12-01 15:34:04.087413921
+0100
--- src/proto/channel.pro 2017-07-15 20:41:05.457918326 +0200
***************
*** 2,7 ****
--- 2,8 ----
void ch_logfile(char_u *fname, char_u *opt);
int ch_log_active(void);
void ch_log(channel_T *ch, char *msg);
+ void ch_logn(channel_T *ch, char *msg, int nr);
void ch_logs(channel_T *ch, char *msg, char *name);
channel_T *add_channel(void);
int has_any_channel(void);
***************
*** 63,69 ****
void job_stop_on_exit(void);
int has_pending_job(void);
void job_check_ended(void);
! job_T *job_start(typval_T *argvars);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
int job_stop(job_T *job, typval_T *argvars);
--- 64,70 ----
void job_stop_on_exit(void);
int has_pending_job(void);
void job_check_ended(void);
! job_T *job_start(typval_T *argvars, jobopt_T *opt_arg);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
int job_stop(job_T *job, typval_T *argvars);
*** ../vim-8.0.0717/src/evalfunc.c 2017-07-11 22:34:47.523932120 +0200
--- src/evalfunc.c 2017-07-15 20:46:46.739331963 +0200
***************
*** 6745,6751 ****
rettv->v_type = VAR_JOB;
if (check_restricted() || check_secure())
return;
! rettv->vval.v_job = job_start(argvars);
}
/*
--- 6745,6751 ----
rettv->v_type = VAR_JOB;
if (check_restricted() || check_secure())
return;
! rettv->vval.v_job = job_start(argvars, NULL);
}
/*
*** ../vim-8.0.0717/src/screen.c 2017-07-12 21:12:38.336024915 +0200
--- src/screen.c 2017-07-15 22:40:33.279714955 +0200
***************
*** 126,138 ****
#endif
static int win_line(win_T *, linenr_T, int, int, int nochange, proftime_T
*syntax_tm);
static int char_needs_redraw(int off_from, int off_to, int cols);
- #ifdef FEAT_RIGHTLEFT
- static void screen_line(int row, int coloff, int endcol, int clear_width, int
rlflag);
- # define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
- #else
- static void screen_line(int row, int coloff, int endcol, int clear_width);
- # define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c))
- #endif
#ifdef FEAT_WINDOWS
static void draw_vsep_win(win_T *wp, int row);
#endif
--- 126,131 ----
***************
*** 411,417 ****
screenline2 + r * cols,
(size_t)cols * sizeof(schar_T));
#endif
! SCREEN_LINE(cmdline_row + r, 0, cols, cols, FALSE);
}
ret = 4;
}
--- 404,410 ----
screenline2 + r * cols,
(size_t)cols * sizeof(schar_T));
#endif
! screen_line(cmdline_row + r, 0, cols, cols, FALSE);
}
ret = 4;
}
***************
*** 1192,1197 ****
--- 1185,1201 ----
}
#endif
+ #ifdef FEAT_TERMINAL
+ if (wp->w_buffer->b_term != NULL)
+ {
+ /* This window contains a terminal, redraw works completely
+ * differently. */
+ term_update_window(wp);
+ wp->w_redr_type = 0;
+ return;
+ }
+ #endif
+
#ifdef FEAT_SEARCH_EXTRA
init_search_hl(wp);
#endif
***************
*** 2886,2892 ****
}
#endif
! SCREEN_LINE(row + W_WINROW(wp), W_WINCOL(wp), (int)W_WIDTH(wp),
(int)W_WIDTH(wp), FALSE);
/*
--- 2890,2896 ----
}
#endif
! screen_line(row + W_WINROW(wp), W_WINCOL(wp), (int)W_WIDTH(wp),
(int)W_WIDTH(wp), FALSE);
/*
***************
*** 3996,4002 ****
#endif
)
{
! SCREEN_LINE(screen_row, W_WINCOL(wp), col, -(int)W_WIDTH(wp),
wp->w_p_rl);
/* Pretend we have finished updating the window. Except when
* 'cursorcolumn' is set. */
--- 4000,4006 ----
#endif
)
{
! screen_line(screen_row, W_WINCOL(wp), col, -(int)W_WIDTH(wp),
wp->w_p_rl);
/* Pretend we have finished updating the window. Except when
* 'cursorcolumn' is set. */
***************
*** 5443,5449 ****
}
#endif
! SCREEN_LINE(screen_row, W_WINCOL(wp), col,
(int)W_WIDTH(wp), wp->w_p_rl);
row++;
--- 5447,5453 ----
}
#endif
! screen_line(screen_row, W_WINCOL(wp), col,
(int)W_WIDTH(wp), wp->w_p_rl);
row++;
***************
*** 5749,5759 ****
)
{
#ifdef FEAT_CONCEAL
! SCREEN_LINE(screen_row, W_WINCOL(wp), col - boguscols,
(int)W_WIDTH(wp), wp->w_p_rl);
boguscols = 0;
#else
! SCREEN_LINE(screen_row, W_WINCOL(wp), col,
(int)W_WIDTH(wp), wp->w_p_rl);
#endif
++row;
--- 5753,5763 ----
)
{
#ifdef FEAT_CONCEAL
! screen_line(screen_row, W_WINCOL(wp), col - boguscols,
(int)W_WIDTH(wp), wp->w_p_rl);
boguscols = 0;
#else
! screen_line(screen_row, W_WINCOL(wp), col,
(int)W_WIDTH(wp), wp->w_p_rl);
#endif
++row;
***************
*** 5959,5964 ****
--- 5963,5979 ----
return FALSE;
}
+ #if defined(FEAT_TERMINAL) || defined(PROTO)
+ /*
+ * Return the index in ScreenLines[] for the current screen line.
+ */
+ int
+ screen_get_current_line_off()
+ {
+ return (int)(current_ScreenLine - ScreenLines);
+ }
+ #endif
+
/*
* Move one "cooked" screen line to the screen, but only the characters that
* have actually changed. Handle insert/delete character.
***************
*** 5970,5985 ****
* When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
* When FALSE and "clear_width" > 0, clear columns "endcol" to
"clear_width"
*/
! static void
screen_line(
int row,
int coloff,
int endcol,
! int clear_width
! #ifdef FEAT_RIGHTLEFT
! , int rlflag
! #endif
! )
{
unsigned off_from;
unsigned off_to;
--- 5985,5997 ----
* When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
* When FALSE and "clear_width" > 0, clear columns "endcol" to
"clear_width"
*/
! void
screen_line(
int row,
int coloff,
int endcol,
! int clear_width,
! int rlflag UNUSED)
{
unsigned off_from;
unsigned off_to;
*** ../vim-8.0.0717/src/proto/screen.pro 2017-04-30 19:39:32.650857838
+0200
--- src/proto/screen.pro 2017-07-15 21:37:38.948173764 +0200
***************
*** 16,21 ****
--- 16,23 ----
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);
+ int screen_get_current_line_off(void);
+ void screen_line(int row, int coloff, int endcol, int clear_width, int
rlflag);
void rl_mirror(char_u *str);
void status_redraw_all(void);
void status_redraw_curbuf(void);
*** ../vim-8.0.0717/src/version.c 2017-07-15 20:05:50.802053721 +0200
--- src/version.c 2017-07-15 22:57:06.592204161 +0200
***************
*** 771,772 ****
--- 771,774 ----
{ /* Add new patch number below this line */
+ /**/
+ 718,
/**/
--
hundred-and-one symptoms of being an internet addict:
163. You go outside for the fresh air (at -30 degrees) but open the
window first to hear new mail arrive.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.