Patch 8.0.1801
Problem: MS-Windows: redirecting terminal output does not work.
Solution: Intercept the text written to the terminal and write it to the
file.
Files: src/terminal.c, src/testdir/test_terminal.vim
*** ../vim-8.0.1800/src/terminal.c 2018-05-06 16:40:12.239619606 +0200
--- src/terminal.c 2018-05-06 21:44:39.219762827 +0200
***************
*** 38,53 ****
* in tl_scrollback are no longer used.
*
* TODO:
! * - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
! * redirection. Probably in call to channel_set_pipes().
! * - Win32: Redirecting output does not work, Test_terminal_redir_file()
* is disabled.
* - Copy text in the vterm to the Vim buffer once in a while, so that
* completion works.
* - When the job only outputs lines, we could handle resizing the terminal
* better: store lines separated by line breaks, instead of screen lines,
* then when the window is resized redraw those lines.
! * - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed)
* - For the GUI fill termios with default values, perhaps like pangoterm:
*
http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
* - When 'encoding' is not utf-8, or the job is using another encoding, setup
--- 38,54 ----
* in tl_scrollback are no longer used.
*
* TODO:
! * - Win32: Redirecting input does not work, half of
Test_terminal_redir_file()
* is disabled.
+ * - Win32: Redirecting output works but includes escape sequences.
+ * - Win32: Make terminal used for :!cmd in the GUI work better. Allow for
+ * redirection.
* - Copy text in the vterm to the Vim buffer once in a while, so that
* completion works.
* - When the job only outputs lines, we could handle resizing the terminal
* better: store lines separated by line breaks, instead of screen lines,
* then when the window is resized redraw those lines.
! * - Redrawing is slow with Athena and Motif. (Ramel Eshed)
* - For the GUI fill termios with default values, perhaps like pangoterm:
*
http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
* - When 'encoding' is not utf-8, or the job is using another encoding, setup
***************
*** 99,109 ****
/* Set when setting the size of a vterm, reset after redrawing. */
int tl_vterm_size_changed;
- /* used when tl_job is NULL and only a pty was created */
- int tl_tty_fd;
- char_u *tl_tty_in;
- char_u *tl_tty_out;
-
int tl_normal_mode; /* TRUE: Terminal-Normal mode */
int tl_channel_closed;
int tl_finish;
--- 100,105 ----
***************
*** 117,122 ****
--- 113,120 ----
#ifdef WIN3264
void *tl_winpty_config;
void *tl_winpty;
+
+ FILE *tl_out_fd;
#endif
#if defined(FEAT_SESSION)
char_u *tl_command;
***************
*** 169,175 ****
/*
* Functions with separate implementation for MS-Windows and Unix-like
systems.
*/
! static int term_and_job_init(term_T *term, typval_T *argvar, char **argv,
jobopt_T *opt);
static int create_pty_only(term_T *term, jobopt_T *opt);
static void term_report_winsize(term_T *term, int rows, int cols);
static void term_free_vterm(term_T *term);
--- 167,173 ----
/*
* Functions with separate implementation for MS-Windows and Unix-like
systems.
*/
! static int term_and_job_init(term_T *term, typval_T *argvar, char **argv,
jobopt_T *opt, jobopt_T *orig_opt);
static int create_pty_only(term_T *term, jobopt_T *opt);
static void term_report_winsize(term_T *term, int rows, int cols);
static void term_free_vterm(term_T *term);
***************
*** 283,289 ****
--- 281,291 ----
static void
setup_job_options(jobopt_T *opt, int rows, int cols)
{
+ #ifndef WIN3264
+ /* Win32: Redirecting the job output won't work, thus always connect
stdout
+ * here. */
if (!(opt->jo_set & JO_OUT_IO))
+ #endif
{
/* Connect stdout to the terminal. */
opt->jo_io[PART_OUT] = JIO_BUFFER;
***************
*** 292,298 ****
--- 294,304 ----
opt->jo_set |= JO_OUT_IO + JO_OUT_BUF + JO_OUT_MODIFIABLE;
}
+ #ifndef WIN3264
+ /* Win32: Redirecting the job output won't work, thus always connect
stderr
+ * here. */
if (!(opt->jo_set & JO_ERR_IO))
+ #endif
{
/* Connect stderr to the terminal. */
opt->jo_io[PART_ERR] = JIO_BUFFER;
***************
*** 350,355 ****
--- 356,362 ----
int res;
buf_T *newbuf;
int vertical = opt->jo_vertical || (cmdmod.split &
WSP_VERT);
+ jobopt_T orig_opt; // only partly filled
if (check_restricted() || check_secure())
return NULL;
***************
*** 517,522 ****
--- 524,532 ----
curbuf->b_p_ma = FALSE;
set_term_and_win_size(term);
+ #ifdef WIN3264
+ mch_memmove(orig_opt.jo_io, opt->jo_io, sizeof(orig_opt.jo_io));
+ #endif
setup_job_options(opt, term->tl_rows, term->tl_cols);
if (flags & TERM_START_NOJOB)
***************
*** 582,588 ****
&& STRCMP(argvar->vval.v_string, "NONE") == 0)
res = create_pty_only(term, opt);
else
! res = term_and_job_init(term, argvar, argv, opt);
newbuf = curbuf;
if (res == OK)
--- 592,598 ----
&& STRCMP(argvar->vval.v_string, "NONE") == 0)
res = create_pty_only(term, opt);
else
! res = term_and_job_init(term, argvar, argv, opt, &orig_opt);
newbuf = curbuf;
if (res == OK)
***************
*** 823,828 ****
--- 833,842 ----
vim_free(term->tl_status_text);
vim_free(term->tl_opencmd);
vim_free(term->tl_eof_chars);
+ #ifdef WIN3264
+ if (term->tl_out_fd != NULL)
+ fclose(term->tl_out_fd);
+ #endif
if (desired_cursor_color == term->tl_cursor_color)
desired_cursor_color = (char_u *)"";
vim_free(term->tl_cursor_color);
***************
*** 918,923 ****
--- 932,948 ----
size_t len = STRLEN(msg);
term_T *term = buffer->b_term;
+ #ifdef WIN3264
+ /* Win32: Cannot redirect output of the job, intercept it here and write
to
+ * the file. */
+ if (term->tl_out_fd != NULL)
+ {
+ ch_log(channel, "Writing %d bytes to output file", (int)len);
+ fwrite(msg, len, 1, term->tl_out_fd);
+ return;
+ }
+ #endif
+
if (term->tl_vterm == NULL)
{
ch_log(channel, "NOT writing %d bytes to terminal", (int)len);
***************
*** 4740,4753 ****
case 0:
if (buf->b_term->tl_job != NULL)
p = buf->b_term->tl_job->jv_tty_out;
- else
- p = buf->b_term->tl_tty_out;
break;
case 1:
if (buf->b_term->tl_job != NULL)
p = buf->b_term->tl_job->jv_tty_in;
- else
- p = buf->b_term->tl_tty_in;
break;
default:
EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
--- 4765,4774 ----
***************
*** 5239,5245 ****
term_T *term,
typval_T *argvar,
char **argv UNUSED,
! jobopt_T *opt)
{
WCHAR *cmd_wchar = NULL;
WCHAR *cwd_wchar = NULL;
--- 5260,5267 ----
term_T *term,
typval_T *argvar,
char **argv UNUSED,
! jobopt_T *opt,
! jobopt_T *orig_opt)
{
WCHAR *cmd_wchar = NULL;
WCHAR *cwd_wchar = NULL;
***************
*** 5393,5398 ****
--- 5415,5433 ----
++job->jv_refcount;
term->tl_job = job;
+ /* Redirecting stdout and stderr doesn't work at the job level. Instead
+ * open the file here and handle it in. opt->jo_io was changed in
+ * setup_job_options(), use the original flags here. */
+ if (orig_opt->jo_io[PART_OUT] == JIO_FILE)
+ {
+ char_u *fname = opt->jo_io_name[PART_OUT];
+
+ ch_log(channel, "Opening output file %s", fname);
+ term->tl_out_fd = mch_fopen((char *)fname, WRITEBIN);
+ if (term->tl_out_fd == NULL)
+ EMSG2(_(e_notopen), fname);
+ }
+
return OK;
failed:
***************
*** 5546,5552 ****
term_T *term,
typval_T *argvar,
char **argv,
! jobopt_T *opt)
{
create_vterm(term, term->tl_rows, term->tl_cols);
--- 5581,5588 ----
term_T *term,
typval_T *argvar,
char **argv,
! jobopt_T *opt,
! jobopt_T *orig_opt UNUSED)
{
create_vterm(term, term->tl_rows, term->tl_cols);
*** ../vim-8.0.1800/src/testdir/test_terminal.vim 2018-05-03
20:40:15.714154543 +0200
--- src/testdir/test_terminal.vim 2018-05-06 21:12:06.003573297 +0200
***************
*** 675,692 ****
endfunc
func Test_terminal_redir_file()
! " TODO: this should work on MS-Window
! if has('unix')
! let cmd = Get_cat_123_cmd()
! let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
! call term_wait(buf)
! call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
! call assert_match('123', readfile('Xfile')[0])
! let g:job = term_getjob(buf)
! call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
! call delete('Xfile')
! bwipe
! endif
if has('unix')
call writefile(['one line'], 'Xfile')
--- 675,689 ----
endfunc
func Test_terminal_redir_file()
! let cmd = Get_cat_123_cmd()
! let buf = term_start(cmd, {'out_io': 'file', 'out_name': 'Xfile'})
! call term_wait(buf)
! call WaitForAssert({-> assert_notequal(0, len(readfile("Xfile")))})
! call assert_match('123', readfile('Xfile')[0])
! let g:job = term_getjob(buf)
! call WaitForAssert({-> assert_equal("dead", job_status(g:job))})
! call delete('Xfile')
! bwipe
if has('unix')
call writefile(['one line'], 'Xfile')
*** ../vim-8.0.1800/src/version.c 2018-05-06 19:19:32.382254324 +0200
--- src/version.c 2018-05-06 21:11:40.931724251 +0200
***************
*** 763,764 ****
--- 763,766 ----
{ /* Add new patch number below this line */
+ /**/
+ 1801,
/**/
--
ARTHUR: Shut up! Will you shut up!
DENNIS: Ah, now we see the violence inherent in the system.
ARTHUR: Shut up!
DENNIS: Oh! Come and see the violence inherent in the system!
HELP! HELP! I'm being repressed!
The Quest for the Holy Grail (Monty Python)
/// 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.