summaryrefslogtreecommitdiff
path: root/src/channel.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-02-03 14:53:10 +0100
committerBram Moolenaar <Bram@vim.org>2019-02-03 14:53:10 +0100
commitaa5df7e3127dff6b7336df0903f5c569a40eb174 (patch)
tree491988c562057debdd52dc8198958e4099fd9452 /src/channel.c
parent01a6c21691631ee55744a1799a9725e5d6521cf4 (diff)
downloadvim-git-aa5df7e3127dff6b7336df0903f5c569a40eb174.tar.gz
patch 8.1.0870: Vim doesn't use the new ConPTY support in Windows 10v8.1.0870
Problem: Vim doesn't use the new ConPTY support in Windows 10. Solution: Use ConPTY support, if available. (Nobuhiro Takasaki, closes #3794)
Diffstat (limited to 'src/channel.c')
-rw-r--r--src/channel.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/src/channel.c b/src/channel.c
index 20cf46238..484d0139b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1720,11 +1720,7 @@ channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
char_u *res;
char_u *p;
- /* If there is only one buffer just get that one. */
- if (head->rq_next == NULL || head->rq_next->rq_next == NULL)
- return channel_get(channel, part, outlen);
-
- /* Concatenate everything into one buffer. */
+ // Concatenate everything into one buffer.
for (node = head->rq_next; node != NULL; node = node->rq_next)
len += node->rq_buflen;
res = lalloc(len + 1, TRUE);
@@ -1738,7 +1734,7 @@ channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
}
*p = NUL;
- /* Free all buffers */
+ // Free all buffers
do
{
p = channel_get(channel, part, NULL);
@@ -1747,16 +1743,37 @@ channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
if (outlen != NULL)
{
+ // Returning the length, keep NUL characters.
*outlen += len;
return res;
}
- /* turn all NUL into NL */
- while (len > 0)
+ // Turn all NUL into NL, so that the result can be used as a string.
+ p = res;
+ while (p < res + len)
{
- --len;
- if (res[len] == NUL)
- res[len] = NL;
+ if (*p == NUL)
+ *p = NL;
+#ifdef WIN32
+ else if (*p == 0x1b)
+ {
+ // crush the escape sequence OSC 0/1/2: ESC ]0;
+ if (p + 3 < res + len
+ && p[1] == ']'
+ && (p[2] == '0' || p[2] == '1' || p[2] == '2')
+ && p[3] == ';')
+ {
+ // '\a' becomes a NL
+ while (p < res + (len - 1) && *p != '\a')
+ ++p;
+ // BEL is zero width characters, suppress display mistake
+ // ConPTY (after 10.0.18317) requires advance checking
+ if (p[-1] == NUL)
+ p[-1] = 0x07;
+ }
+ }
+#endif
+ ++p;
}
return res;
@@ -4330,7 +4347,7 @@ channel_parse_messages(void)
channel = first_channel;
continue;
}
- if (channel->ch_to_be_freed)
+ if (channel->ch_to_be_freed || channel->ch_killing)
{
channel_free(channel);
/* channel has been freed, start over */
@@ -4930,6 +4947,28 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
opt->jo_set2 |= JO2_TERM_KILL;
opt->jo_term_kill = tv_get_string_chk(item);
}
+ else if (STRCMP(hi->hi_key, "term_mode") == 0)
+ {
+ char_u *p;
+
+ if (!(supported2 & JO2_TERM_MODE))
+ break;
+ opt->jo_set2 |= JO2_TERM_MODE;
+ p = tv_get_string_chk(item);
+ if (p == NULL)
+ {
+ semsg(_(e_invargval), "term_mode");
+ return FAIL;
+ }
+ // Allow empty string, "winpty", "conpty".
+ if (!(*p == NUL || STRCMP(p, "winpty") == 0
+ || STRCMP(p, "conpty") == 0))
+ {
+ semsg(_(e_invargval), "term_mode");
+ return FAIL;
+ }
+ opt->jo_term_mode = p[0];
+ }
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
else if (STRCMP(hi->hi_key, "ansi_colors") == 0)
{
@@ -5440,6 +5479,16 @@ job_cleanup(job_T *job)
channel_need_redraw = TRUE;
}
+ if (job->jv_channel != NULL
+ && job->jv_channel->ch_anonymous_pipe && !job->jv_channel->ch_killing)
+ {
+ ++safe_to_invoke_callback;
+ channel_free_contents(job->jv_channel);
+ job->jv_channel->ch_job = NULL;
+ job->jv_channel = NULL;
+ --safe_to_invoke_callback;
+ }
+
// Do not free the job in case the close callback of the associated channel
// isn't invoked yet and may get information by job_info().
if (job->jv_refcount == 0 && !job_channel_still_useful(job))