forked from aniani/vim
patch 8.0.1074: ":term NONE" does not work on MS-Windows
Problem: ":term NONE" does not work on MS-Windows. Solution: Make it work. Split "pty" into "pty_in" and "pty_out". (Yasuhiro Matsumoto, closes #2058, closes #2045)
This commit is contained in:
107
src/terminal.c
107
src/terminal.c
@@ -38,8 +38,7 @@
|
||||
* in tl_scrollback are no longer used.
|
||||
*
|
||||
* TODO:
|
||||
* - ":term NONE" does not work on MS-Windows.
|
||||
* https://github.com/vim/vim/pull/2056
|
||||
* - patch to use GUI or cterm colors for vterm. Yasuhiro, #2067
|
||||
* - Redirecting output does not work on MS-Windows.
|
||||
* - implement term_setsize()
|
||||
* - add test for giving error for invalid 'termsize' value.
|
||||
@@ -97,7 +96,8 @@ struct terminal_S {
|
||||
|
||||
/* used when tl_job is NULL and only a pty was created */
|
||||
int tl_tty_fd;
|
||||
char_u *tl_tty_name;
|
||||
char_u *tl_tty_in;
|
||||
char_u *tl_tty_out;
|
||||
|
||||
int tl_normal_mode; /* TRUE: Terminal-Normal mode */
|
||||
int tl_channel_closed;
|
||||
@@ -2666,14 +2666,32 @@ f_term_gettty(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
buf_T *buf = term_get_buf(argvars);
|
||||
char_u *p;
|
||||
int num = 0;
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
if (buf == NULL)
|
||||
return;
|
||||
if (buf->b_term->tl_job != NULL)
|
||||
p = buf->b_term->tl_job->jv_tty_name;
|
||||
else
|
||||
p = buf->b_term->tl_tty_name;
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
num = get_tv_number(&argvars[1]);
|
||||
|
||||
switch (num)
|
||||
{
|
||||
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]));
|
||||
return;
|
||||
}
|
||||
if (p != NULL)
|
||||
rettv->vval.v_string = vim_strsave(p);
|
||||
}
|
||||
@@ -3055,7 +3073,6 @@ term_and_job_init(
|
||||
HANDLE child_thread_handle;
|
||||
void *winpty_err;
|
||||
void *spawn_config = NULL;
|
||||
char buf[MAX_PATH];
|
||||
garray_T ga;
|
||||
char_u *cmd;
|
||||
|
||||
@@ -3094,7 +3111,6 @@ term_and_job_init(
|
||||
if (term->tl_winpty == NULL)
|
||||
goto failed;
|
||||
|
||||
/* TODO: if the command is "NONE" only create a pty. */
|
||||
spawn_config = winpty_spawn_config_new(
|
||||
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN |
|
||||
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
|
||||
@@ -3162,9 +3178,10 @@ term_and_job_init(
|
||||
job->jv_proc_info.dwProcessId = GetProcessId(child_process_handle);
|
||||
job->jv_job_object = jo;
|
||||
job->jv_status = JOB_STARTED;
|
||||
sprintf(buf, "winpty://%lu",
|
||||
GetProcessId(winpty_agent_process(term->tl_winpty)));
|
||||
job->jv_tty_name = vim_strsave((char_u*)buf);
|
||||
job->jv_tty_in = utf16_to_enc(
|
||||
(short_u*)winpty_conin_name(term->tl_winpty), NULL);
|
||||
job->jv_tty_out = utf16_to_enc(
|
||||
(short_u*)winpty_conout_name(term->tl_winpty), NULL);
|
||||
++job->jv_refcount;
|
||||
term->tl_job = job;
|
||||
|
||||
@@ -3205,9 +3222,68 @@ failed:
|
||||
}
|
||||
|
||||
static int
|
||||
create_pty_only(term_T *term, jobopt_T *opt)
|
||||
create_pty_only(term_T *term, jobopt_T *options)
|
||||
{
|
||||
/* TODO: implement this */
|
||||
HANDLE hPipeIn = INVALID_HANDLE_VALUE;
|
||||
HANDLE hPipeOut = INVALID_HANDLE_VALUE;
|
||||
char in_name[80], out_name[80];
|
||||
channel_T *channel = NULL;
|
||||
|
||||
create_vterm(term, term->tl_rows, term->tl_cols);
|
||||
|
||||
vim_snprintf(in_name, sizeof(in_name), "\\\\.\\pipe\\vim-%d-in-%d",
|
||||
GetCurrentProcessId(),
|
||||
curbuf->b_fnum);
|
||||
hPipeIn = CreateNamedPipe(in_name, PIPE_ACCESS_OUTBOUND,
|
||||
PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
0, 0, NMPWAIT_NOWAIT, NULL);
|
||||
if (hPipeIn == INVALID_HANDLE_VALUE)
|
||||
goto failed;
|
||||
|
||||
vim_snprintf(out_name, sizeof(out_name), "\\\\.\\pipe\\vim-%d-out-%d",
|
||||
GetCurrentProcessId(),
|
||||
curbuf->b_fnum);
|
||||
hPipeOut = CreateNamedPipe(out_name, PIPE_ACCESS_INBOUND,
|
||||
PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
0, 0, 0, NULL);
|
||||
if (hPipeOut == INVALID_HANDLE_VALUE)
|
||||
goto failed;
|
||||
|
||||
ConnectNamedPipe(hPipeIn, NULL);
|
||||
ConnectNamedPipe(hPipeOut, NULL);
|
||||
|
||||
term->tl_job = job_alloc();
|
||||
if (term->tl_job == NULL)
|
||||
goto failed;
|
||||
++term->tl_job->jv_refcount;
|
||||
|
||||
/* behave like the job is already finished */
|
||||
term->tl_job->jv_status = JOB_FINISHED;
|
||||
|
||||
channel = add_channel();
|
||||
if (channel == NULL)
|
||||
goto failed;
|
||||
term->tl_job->jv_channel = channel;
|
||||
channel->ch_keep_open = TRUE;
|
||||
channel->ch_named_pipe = TRUE;
|
||||
|
||||
channel_set_pipes(channel,
|
||||
(sock_T)hPipeIn,
|
||||
(sock_T)hPipeOut,
|
||||
(sock_T)hPipeOut);
|
||||
channel_set_job(channel, term->tl_job, options);
|
||||
term->tl_job->jv_tty_in = vim_strsave((char_u*)in_name);
|
||||
term->tl_job->jv_tty_out = vim_strsave((char_u*)out_name);
|
||||
|
||||
return OK;
|
||||
|
||||
failed:
|
||||
if (hPipeIn != NULL)
|
||||
CloseHandle(hPipeIn);
|
||||
if (hPipeOut != NULL)
|
||||
CloseHandle(hPipeOut);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -3234,7 +3310,8 @@ term_free_vterm(term_T *term)
|
||||
static void
|
||||
term_report_winsize(term_T *term, int rows, int cols)
|
||||
{
|
||||
winpty_set_size(term->tl_winpty, cols, rows, NULL);
|
||||
if (term->tl_winpty)
|
||||
winpty_set_size(term->tl_winpty, cols, rows, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
|
Reference in New Issue
Block a user