aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-05-02 23:24:37 +0200
committerGitHub <noreply@github.com>2022-05-02 23:24:37 +0200
commitddf7bb24f98b468d2bc6c16c6f300570fc6530f5 (patch)
tree8d2c78c2fa94ee7c7bfd40d7cc2f00bc54801eaf /src
parenta1542b091dd7b919fa8524c1c909ef897dde9299 (diff)
parentad63b94b03c166f37bda477db6cbac2a9583d586 (diff)
downloadrneovim-ddf7bb24f98b468d2bc6c16c6f300570fc6530f5.tar.gz
rneovim-ddf7bb24f98b468d2bc6c16c6f300570fc6530f5.tar.bz2
rneovim-ddf7bb24f98b468d2bc6c16c6f300570fc6530f5.zip
Merge pull request #18357 from bfredl/ui_stdin
feat(ui): allow embedder to emulate "cat data | nvim -" behaviour
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c16
-rw-r--r--src/nvim/fileio.c20
-rw-r--r--src/nvim/globals.h4
-rw-r--r--src/nvim/main.c2
4 files changed, 31 insertions, 11 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 997f0c218a..f449ccc3c7 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -283,6 +283,22 @@ static void ui_set_option(UI *ui, bool init, String name, Object value, Error *e
return;
}
+ if (strequal(name.data, "stdin_fd")) {
+ if (value.type != kObjectTypeInteger || value.data.integer < 0) {
+ api_set_error(error, kErrorTypeValidation, "stdin_fd must be a non-negative Integer");
+ return;
+ }
+
+ if (starting != NO_SCREEN) {
+ api_set_error(error, kErrorTypeValidation,
+ "stdin_fd can only be used with first attached ui");
+ return;
+ }
+
+ stdin_fd = (int)value.data.integer;
+ return;
+ }
+
// LEGACY: Deprecated option, use `ext_cmdline` instead.
bool is_popupmenu = strequal(name.data, "popupmenu_external");
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 7ca7abccdc..95c373ec5c 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -176,7 +176,7 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip,
linenr_T lines_to_read, exarg_T *eap, int flags, bool silent)
{
- int fd = 0;
+ int fd = stdin_fd >= 0 ? stdin_fd : 0;
int newfile = (flags & READ_NEW);
int check_readonly;
int filtering = (flags & READ_FILTER);
@@ -1722,17 +1722,19 @@ failed:
xfree(buffer);
if (read_stdin) {
- close(0);
+ close(fd);
+ if (stdin_fd < 0) {
#ifndef WIN32
- // On Unix, use stderr for stdin, makes shell commands work.
- vim_ignored = dup(2);
+ // On Unix, use stderr for stdin, makes shell commands work.
+ vim_ignored = dup(2);
#else
- // On Windows, use the console input handle for stdin.
- HANDLE conin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,
- OPEN_EXISTING, 0, (HANDLE)NULL);
- vim_ignored = _open_osfhandle(conin, _O_RDONLY);
+ // On Windows, use the console input handle for stdin.
+ HANDLE conin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING, 0, (HANDLE)NULL);
+ vim_ignored = _open_osfhandle(conin, _O_RDONLY);
#endif
+ }
}
if (tmpname != NULL) {
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 6443759a39..3ae0d32d8f 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -507,6 +507,9 @@ EXTERN int v_dying INIT(= 0);
EXTERN int stdin_isatty INIT(= true);
// is stdout a terminal?
EXTERN int stdout_isatty INIT(= true);
+/// filedesc set by embedder for reading first buffer like `cmd | nvim -`
+EXTERN int stdin_fd INIT(= -1);
+
// true when doing full-screen output, otherwise only writing some messages.
// volatile because it is used in a signal handler.
EXTERN volatile int full_screen INIT(= false);
@@ -847,7 +850,6 @@ EXTERN linenr_T printer_page_num;
EXTERN bool typebuf_was_filled INIT(= false); // received text from client
// or from feedkeys()
-
#ifdef BACKSLASH_IN_FILENAME
EXTERN char psepc INIT(= '\\'); // normal path separator character
EXTERN char psepcN INIT(= '/'); // abnormal path separator character
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 952064ab73..5a496a10b4 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 || stdin_fd >= 0) && !recoverymode) {
read_stdin();
}