# HG changeset patch # User Christian Brabandt # Date 1504362604 -7200 # Node ID 66fa8eabbd6e52470e026cd195ba12c075c31947 # Parent bf16ab3c2341c431d9b135313b4dc6892cf46e4c patch 8.0.1035: sending buffer lines to terminal doesn't work on MS-Windows commit https://github.com/vim/vim/commit/ef68e4fa528165f8dd63156feeffc1af629b8d8a Author: Bram Moolenaar Date: Sat Sep 2 16:28:36 2017 +0200 patch 8.0.1035: sending buffer lines to terminal doesn't work on MS-Windows Problem: Sending buffer lines to terminal doesn't work on MS-Windows. Solution: Use CR instead of NL after every line. Make the EOF text work properly. Add the ++eof argument to :terminal. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -8141,6 +8141,12 @@ term_start({cmd}, {options}) *term_st have "%d" where the buffer number goes, e.g. "10split|buffer %d"; when not specified "botright sbuf %d" is used + "eof_chars" Text to send after all buffer lines were + written to the terminal. When not set + CTRL-D is used. For Python use CTRL-Z or + "exit()". For a shell use "exit". A CR + is always added. + {only on MS-Windows} {only available when compiled with the |+terminal| feature} diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt --- a/runtime/doc/terminal.txt +++ b/runtime/doc/terminal.txt @@ -133,6 +133,14 @@ Syntax ~ height. ++cols={width} Use {width} for the terminal window width. + ++eof={text} when using [range], text to send after + the last line was written. The default + is to send CTRL-D. A CR is appended. + E.g. for a shell use "++eof=exit" and + for Python "++eof=exit()". Special + codes can be used like with `:map`, + e.g. "" for CTRL-Z. + {only on MS-Windows} If you want to use more options use the |term_start()| function. @@ -141,11 +149,13 @@ When the buffer associated with the term is killed, similar to calling `job_stop(job, "kill")` So long as the job is running the window behaves like it contains a modified -buffer. Trying to close the window with `CTRL-W :close` or `CTRL-W :hide` -fails, unless "!" is added, in which case the job is ended. The text in the -window is lost. The buffer still exists, but getting it in a window with -`:buffer` will show an -empty buffer. +buffer. Trying to close the window with `CTRL-W :quit` fails. When using +`CTRL-W :quit!` the job is ended. The text in the window is lost. The buffer +still exists, but getting it in a window with `:buffer` will show an empty +buffer. + +Trying to close the window with `CTRL-W :close` also fails. Using +`CTRL-W :close!` will close the window and make the buffer hidden. You can use `CTRL-W :hide` to close the terminal window and make the buffer hidden, the job keeps running. The `:buffer` command can be used to turn the diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -1300,11 +1300,16 @@ write_buf_line(buf_T *buf, linenr_T lnum return; memcpy((char *)p, (char *)line, len); - for (i = 0; i < len; ++i) - if (p[i] == NL) - p[i] = NUL; - - p[len] = NL; + if (channel->ch_write_text_mode) + p[len] = CAR; + else + { + for (i = 0; i < len; ++i) + if (p[i] == NL) + p[i] = NUL; + + p[len] = NL; + } p[len + 1] = NUL; channel_send(channel, PART_IN, p, len + 1, "write_buf_line"); vim_free(p); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1632,6 +1632,7 @@ struct channel_S { int ch_last_msg_id; /* ID of the last message */ chanpart_T ch_part[PART_COUNT]; /* info for socket, out, err and in */ + int ch_write_text_mode; /* write buffer lines with CR, not NL */ char *ch_hostname; /* only for socket, allocated */ int ch_port; /* only for socket */ diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -496,6 +496,24 @@ ex_terminal(exarg_T *eap) opt.jo_term_cols = atoi((char *)ep + 1); p = skiptowhite(cmd); } + else if ((int)(p - cmd) == 3 && STRNICMP(cmd, "eof", 3) == 0 + && ep != NULL) + { +# ifdef WIN3264 + char_u *buf = NULL; + char_u *keys; + + p = skiptowhite(cmd); + *p = NUL; + keys = replace_termcodes(ep + 1, &buf, TRUE, TRUE, TRUE); + opt.jo_set2 |= JO2_EOF_CHARS; + opt.jo_eof_chars = vim_strsave(keys); + vim_free(buf); + *p = ' '; +# else + p = skiptowhite(cmd); +# endif + } else { if (*p) @@ -3069,8 +3087,6 @@ term_and_job_init( if (job == NULL) goto failed; - /* TODO: when all lines are written and the fd is closed, the command - * doesn't get EOF and hangs. */ if (opt->jo_set & JO_IN_BUF) job->jv_in_buf = buflist_findnr(opt->jo_io_buf[PART_IN]); @@ -3092,6 +3108,9 @@ term_and_job_init( GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)); + /* Write lines with CR instead of NL. */ + channel->ch_write_text_mode = TRUE; + jo = CreateJobObject(NULL, NULL); if (jo == NULL) goto failed; @@ -3208,8 +3227,15 @@ term_send_eof(channel_T *ch) for (term = first_term; term != NULL; term = term->tl_next) if (term->tl_job == ch->ch_job) - channel_send(ch, PART_IN, term->tl_eof_chars != NULL - ? term->tl_eof_chars : (char_u *)"\004\r\n", 3, NULL); + { + if (term->tl_eof_chars != NULL) + channel_send(ch, PART_IN, term->tl_eof_chars, + (int)STRLEN(term->tl_eof_chars), NULL); + else + /* Default: CTRL-D */ + channel_send(ch, PART_IN, (char_u *)"\004", 1, NULL); + channel_send(ch, PART_IN, (char_u *)"\r", 1, NULL); + } } # else diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 1035, +/**/ 1034, /**/ 1033,