main: Simplify code that deals with early user input

A read stream will be started before the first ex command is processed. This
stream will be used to read early user input before handling control over to the
UI module.

Which stdio stream will be used depends on which types of file descriptors are
connected, and whether the "-" argument was passed.
This commit is contained in:
Thiago de Arruda 2015-03-18 12:46:04 -03:00
parent 8b7b71f474
commit 4d63d99174
2 changed files with 32 additions and 30 deletions

View File

@ -268,16 +268,26 @@ int main(int argc, char **argv)
/* Set the break level after the terminal is initialized. */
debug_break_level = params.use_debug_break_level;
bool reading_input = !params.headless && (params.input_isatty
|| params.output_isatty || params.err_isatty);
if (reading_input) {
// Its possible that one of the startup commands(arguments, sourced scripts
// or plugins) will prompt the user, so start reading from a tty stream
// now.
int fd = fileno(stdin);
if (!params.input_isatty || params.edit_type == EDIT_STDIN) {
// use stderr or stdout since stdin is not a tty and/or could be used to
// read the file we'll edit when the "-" argument is given(eg: cat file |
// nvim -)
fd = params.err_isatty ? fileno(stderr) : fileno(stdout);
}
input_start_stdin(fd);
}
/* Execute --cmd arguments. */
exe_pre_commands(&params);
if (!params.headless && params.input_isatty) {
// Its possible that one of the scripts sourced at startup will prompt the
// user, so start stdin now. TODO(tarruda): This is only for compatibility.
// Startup user prompting should be done in the VimEnter autocmd
input_start_stdin();
}
/* Source startup scripts. */
source_startup_scripts(&params);
@ -358,22 +368,19 @@ int main(int argc, char **argv)
if (params.edit_type == EDIT_STDIN && !recoverymode)
read_stdin();
if (reading_input && (need_wait_return || msg_didany)) {
// Since at this point there's no UI instance running yet, error messages
// would have been printed to stdout. Before starting (which can result in
// a alternate screen buffer being shown) we need confirmation that the
// user has seen the messages and that is done with a call to wait_return.
TIME_MSG("waiting for return");
wait_return(TRUE);
}
if (!params.headless) {
if ((params.output_isatty || params.err_isatty)
&& (need_wait_return || msg_didany)) {
// Since at this point there's no UI instance running yet, error messages
// would have been printed to stdout. Before starting (which can result in
// a alternate screen buffer being shown) we need confirmation that the
// user has seen the messages and that is done with a call to wait_return.
TIME_MSG("waiting for return");
wait_return(TRUE);
}
if (params.input_isatty) {
// Stop reading from stdin, the UI module will take over now.
input_stop_stdin();
}
// Stop reading from stdin, the UI layer will take over now
input_stop_stdin();
ui_builtin_start();
}
@ -1465,11 +1472,6 @@ static void check_tty(mparm_T *parmp)
TIME_MSG("Warning delay");
}
if (parmp->edit_type != EDIT_STDIN && !parmp->input_isatty) {
// read commands from directly from stdin
input_start_stdin();
}
}
/*

View File

@ -46,7 +46,7 @@ void input_init(void)
input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN);
}
void input_start_stdin(void)
void input_start_stdin(int fd)
{
if (read_stream) {
return;
@ -54,7 +54,7 @@ void input_start_stdin(void)
read_buffer = rbuffer_new(READ_BUFFER_SIZE);
read_stream = rstream_new(read_cb, read_buffer, NULL);
rstream_set_file(read_stream, fileno(stdin));
rstream_set_file(read_stream, fd);
rstream_start(read_stream);
}
@ -69,7 +69,7 @@ void input_stop_stdin(void)
read_stream = NULL;
}
// Low level input function.
// Low level input function
int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
{
if (rbuffer_pending(input_buffer)) {