diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2023-01-03 02:54:53 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2023-01-05 17:10:02 +0100 |
commit | f43de742e881e54a3602e00c8c247cecca65a266 (patch) | |
tree | b53c6c40989690a37a2bd278587aaba64e7ff332 /src/nvim/lua/executor.c | |
parent | adef308a5925a3b967af3bd7c598074e5b6cae18 (diff) | |
download | rneovim-f43de742e881e54a3602e00c8c247cecca65a266.tar.gz rneovim-f43de742e881e54a3602e00c8c247cecca65a266.tar.bz2 rneovim-f43de742e881e54a3602e00c8c247cecca65a266.zip |
feat(lua): execute stdin ("-") as Lua
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r-- | src/nvim/lua/executor.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 4b08603dd0..b7844363c5 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -335,7 +335,7 @@ static int nlua_thr_api_nvim__get_runtime(lua_State *lstate) /// @see https://github.com/premake/premake-core/blob/1c1304637f4f5e50ba8c57aae8d1d80ec3b7aaf2/src/host/premake.c#L563-L594 /// /// @returns number of args -int nlua_set_argv(char **argv, int argc, int lua_arg0) +int nlua_init_argv(char **argv, int argc, int lua_arg0) { lua_State *const L = global_lstate; lua_newtable(L); // _G.arg @@ -1711,21 +1711,62 @@ void ex_luafile(exarg_T *const eap) nlua_exec_file((const char *)eap->arg); } -/// Executes Lua code from a file. +/// Executes Lua code from a file or "-" (stdin). /// -/// Note: we call the Lua global loadfile as opposed to calling luaL_loadfile -/// in case loadfile was overridden in the user's environment. +/// Calls the Lua `loadfile` global as opposed to `luaL_loadfile` in case `loadfile` was overridden +/// in the user environment. /// -/// @param path path of the file +/// @param path Path to the file, may be "-" (stdin) during startup. /// -/// @return true if everything ok, false if there was an error (echoed) +/// @return true on success, false on error (echoed) or user canceled (CTRL-c) while reading "-" +/// (stdin). bool nlua_exec_file(const char *path) FUNC_ATTR_NONNULL_ALL { lua_State *const lstate = global_lstate; + if (!strequal(path, "-")) { + lua_getglobal(lstate, "loadfile"); + lua_pushstring(lstate, path); + } else { + 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, + kFileReadOnly|kFileNonBlocking); + assert(stdin_dup != NULL); + + StringBuilder sb = KV_INITIAL_VALUE; + kv_resize(sb, 64); + ptrdiff_t read_size = -1; + // Read all input from stdin, unless interrupted (ctrl-c). + while (true) { + if (got_int) { // User canceled. + return false; + } + read_size = file_read(stdin_dup, IObuff, 64); + if (read_size < 0) { // Error. + return false; + } + kv_concat_len(sb, IObuff, (size_t)read_size); + if (read_size < 64) { // EOF. + break; + } + } + kv_push(sb, NUL); + file_free(stdin_dup, false); - lua_getglobal(lstate, "loadfile"); - lua_pushstring(lstate, path); + lua_getglobal(lstate, "loadstring"); + lua_pushstring(lstate, sb.items); + kv_destroy(sb); + } if (nlua_pcall(lstate, 1, 2)) { nlua_error(lstate, _("E5111: Error calling lua: %.*s")); |