From 619c8f4b9143e4dea0fb967ccdce594e14956ed3 Mon Sep 17 00:00:00 2001 From: hlpr98 Date: Sat, 16 Apr 2022 14:46:20 +0200 Subject: [PATCH] feat(api): support handling stdin stream in remote ui --- src/nvim/api/vim.c | 32 ++++++++++++++++++++++++++++++++ src/nvim/globals.h | 4 ++++ src/nvim/main.c | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 061653c5af..9c34c912c0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2661,3 +2661,35 @@ end: xfree(cmdline); return result; } + +/// Invokes the nvim server to read from stdin when it is not a tty +/// +/// It enables functionalities like: +/// - echo "1f u c4n r34d th1s u r34lly n33d t0 g37 r357"| nvim - +/// - cat path/to/a/file | nvim - +/// It has to be called before |nvim_ui_attach()| is called in order +/// to ensure proper functioning. +/// +/// @param channel_id: The channel id of the GUI-client +/// @param filedesc: The file descriptor of the GUI-client process' stdin +/// @param implicit: Tells if read_stdin call is implicit. +/// i.e for cases like `echo xxx | nvim` +/// @param[out] err Error details, if any +void nvim_read_stdin(uint64_t channel_id, Integer filedesc, Error *err) +FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY +{ + if (starting != NO_SCREEN) { + api_set_error(err, kErrorTypeValidation, + "nvim_read_stdin must be called before nvim_ui_attach"); + return; + } + if (filedesc < 0) { + api_set_error(err, kErrorTypeValidation, + "file descriptor must be non-negative"); + return; + } + + stdin_filedesc = (int)filedesc; + implicit_readstdin = implicit; + return; +} diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 6443759a39..8d03bdf000 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -704,6 +704,7 @@ EXTERN int RedrawingDisabled INIT(= 0); EXTERN int readonlymode INIT(= false); // Set to true for "view" EXTERN int recoverymode INIT(= false); // Set to true for "-r" option +EXTERN int stdin_filedesc INIT(= -1); // stdin filedesc set by embedder // typeahead buffer EXTERN typebuf_T typebuf INIT(= { NULL, NULL, 0, 0, 0, 0, 0, 0, 0 }); @@ -847,6 +848,9 @@ EXTERN linenr_T printer_page_num; EXTERN bool typebuf_was_filled INIT(= false); // received text from client // or from feedkeys() +EXTERN bool implicit_readstdin INIT(= false); // Used in embed job created + // by TUI process only in + // builtin tui #ifdef BACKSLASH_IN_FILENAME EXTERN char psepc INIT(= '\\'); // normal path separator character diff --git a/src/nvim/main.c b/src/nvim/main.c index 952064ab73..253a89467e 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -454,7 +454,7 @@ int main(int argc, char **argv) // writing end of the pipe doesn't like, e.g., in case stdin and stderr // are the same terminal: "cat | vim -". // Using autocommands here may cause trouble... - if (params.edit_type == EDIT_STDIN && !recoverymode) { + if ((params.edit_type == EDIT_STDIN || implicit_readstdin) && !recoverymode) { read_stdin(); }