aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--src/nvim/main.c1
-rw-r--r--src/nvim/os/fileio.c16
-rw-r--r--src/nvim/os/fs.c17
-rw-r--r--src/nvim/quickfix.c4
-rw-r--r--test/functional/ui/embed_spec.lua73
6 files changed, 90 insertions, 23 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 36b42e28e3..e83fc25f88 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -409,6 +409,8 @@ The following changes to existing APIs or features add new behavior.
• |nvim_open_win()| and |nvim_win_set_config()| now support opening normal (split)
windows, and moving floating windows into split windows.
+• 'errorfile' (|-q|) accepts `-` as an alias for stdin.
+
==============================================================================
REMOVED FEATURES *news-removed*
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 6d71dc618a..f858313682 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1016,6 +1016,7 @@ static bool edit_stdin(mparm_T *parmp)
&& !(embedded_mode && stdin_fd <= 0)
&& (!exmode_active || parmp->input_istext)
&& !stdin_isatty
+ && parmp->edit_type <= EDIT_STDIN
&& parmp->scriptin == NULL; // `-s -` was not given.
return parmp->had_stdin_file || implicit;
}
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 0141db7553..d24681a156 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -25,10 +25,6 @@
#include "nvim/rbuffer_defs.h"
#include "nvim/types_defs.h"
-#ifdef MSWIN
-# include "nvim/os/os_win_console.h"
-#endif
-
#ifdef HAVE_SYS_UIO_H
# include <sys/uio.h>
#endif
@@ -179,17 +175,7 @@ FileDescriptor *file_open_stdin(void)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
int error;
- int stdin_dup_fd;
- if (stdin_fd > 0) {
- stdin_dup_fd = stdin_fd;
- } else {
- stdin_dup_fd = os_dup(STDIN_FILENO);
-#ifdef MSWIN
- // Replace the original stdin with the console input handle.
- os_replace_stdin_to_conin();
-#endif
- }
- FileDescriptor *const stdin_dup = file_open_fd_new(&error, stdin_dup_fd,
+ FileDescriptor *const stdin_dup = file_open_fd_new(&error, os_open_stdin_fd(),
kFileReadOnly|kFileNonBlocking);
assert(stdin_dup != NULL);
if (error != 0) {
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index d80539708d..566d51f30a 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -55,6 +55,7 @@
#ifdef MSWIN
# include "nvim/mbyte.h"
# include "nvim/option.h"
+# include "nvim/os/os_win_console.h"
# include "nvim/strings.h"
#endif
@@ -541,6 +542,22 @@ os_dup_dup:
return ret;
}
+/// Open the file descriptor for stdin.
+int os_open_stdin_fd(void)
+{
+ int stdin_dup_fd;
+ if (stdin_fd > 0) {
+ stdin_dup_fd = stdin_fd;
+ } else {
+ stdin_dup_fd = os_dup(STDIN_FILENO);
+#ifdef MSWIN
+ // Replace the original stdin with the console input handle.
+ os_replace_stdin_to_conin();
+#endif
+ }
+ return stdin_dup_fd;
+}
+
/// Read from a file
///
/// Handles EINTR and ENOMEM, but not other errors.
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 801c00933a..14758c8cea 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1065,7 +1065,9 @@ static int qf_setup_state(qfstate_T *pstate, char *restrict enc, const char *res
}
if (efile != NULL
- && (pstate->fd = os_fopen(efile, "r")) == NULL) {
+ && (pstate->fd = (strequal(efile, "-")
+ ? fdopen(os_open_stdin_fd(), "r")
+ : os_fopen(efile, "r"))) == NULL) {
semsg(_(e_openerrf), efile);
return FAIL;
}
diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua
index f6bdd2215d..0445476780 100644
--- a/test/functional/ui/embed_spec.lua
+++ b/test/functional/ui/embed_spec.lua
@@ -3,6 +3,7 @@ local uv = vim.uv
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
+local api = helpers.api
local feed = helpers.feed
local eq = helpers.eq
local neq = helpers.neq
@@ -11,6 +12,7 @@ local ok = helpers.ok
local fn = helpers.fn
local nvim_prog = helpers.nvim_prog
local retry = helpers.retry
+local write_file = helpers.write_file
local function test_embed(ext_linegrid)
local screen
@@ -113,26 +115,83 @@ describe('--embed UI', function()
writer:close()
end)
- screen:expect {
- grid = [[
+ screen:expect [[
^hello nvim |
from external input |
{1:~ }|*5
|
- ]],
- }
+ ]]
-- stdin (rpc input) still works
feed 'o'
- screen:expect {
- grid = [[
+ screen:expect [[
hello nvim |
^ |
from external input |
{1:~ }|*4
{2:-- INSERT --} |
- ]],
+ ]]
+ end)
+
+ it('can pass stdin to -q - #17523', function()
+ write_file(
+ 'Xbadfile.c',
+ [[
+ /* some file with an error */
+ main() {
+ functionCall(arg; arg, arg);
+ return 666
+ }
+ ]]
+ )
+ finally(function()
+ os.remove('Xbadfile.c')
+ end)
+
+ local pipe = assert(uv.pipe())
+
+ local writer = assert(uv.new_pipe(false))
+ writer:open(pipe.write)
+
+ clear { args_rm = { '--headless' }, args = { '-q', '-' }, io_extra = pipe.read }
+
+ -- attach immediately after startup, for early UI
+ local screen = Screen.new(60, 8)
+ screen.rpc_async = true -- Avoid hanging. #24888
+ screen:attach { stdin_fd = 3 }
+ screen:set_default_attr_ids {
+ [1] = { bold = true, foreground = Screen.colors.Blue1 },
+ [2] = { bold = true },
}
+
+ writer:write [[Xbadfile.c:4:12: error: expected ';' before '}' token]]
+ writer:shutdown(function()
+ writer:close()
+ end)
+
+ screen:expect [[
+ /* some file with an error */ |
+ main() { |
+ functionCall(arg; arg, arg); |
+ return 66^6 |
+ } |
+ {1:~ }|*2
+ (1 of 1): error: expected ';' before '}' token |
+ ]]
+
+ -- stdin (rpc input) still works
+ feed 'A'
+ screen:expect [[
+ /* some file with an error */ |
+ main() { |
+ functionCall(arg; arg, arg); |
+ return 666^ |
+ } |
+ {1:~ }|*2
+ {2:-- INSERT --} |
+ ]]
+
+ eq('-', api.nvim_get_option_value('errorfile', {}))
end)
it('only sets background colors once even if overridden', function()