diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-12-01 23:15:16 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-01 23:15:16 -0800 |
commit | 735d89d09e5cf50886b927ce4ec93b9098da259d (patch) | |
tree | dd62308f90e4282a46094493d5e167aab8526ff1 /src/nvim/api/vim.c | |
parent | 70b606166640d043fc7b78a52b89ff1bba798b6a (diff) | |
parent | b1991f66d5845ccb72c73fdf39153a0e1fbb1124 (diff) | |
download | rneovim-735d89d09e5cf50886b927ce4ec93b9098da259d.tar.gz rneovim-735d89d09e5cf50886b927ce4ec93b9098da259d.tar.bz2 rneovim-735d89d09e5cf50886b927ce4ec93b9098da259d.zip |
Merge #11159 'API: nvim_exec'
API: nvim_exec: function to source multiline Vimscript ("anonymous :source")
Diffstat (limited to 'src/nvim/api/vim.c')
-rw-r--r-- | src/nvim/api/vim.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index e4a9bd64ff..6763a3a936 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -25,6 +25,7 @@ #include "nvim/highlight.h" #include "nvim/window.h" #include "nvim/types.h" +#include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/screen.h" #include "nvim/memline.h" @@ -72,10 +73,70 @@ void api_vim_free_all_mem(void) map_free(String, handle_T)(namespace_ids); } +/// Executes Vimscript (multiline block of Ex-commands), like anonymous +/// |:source|. +/// +/// Optionally returns (non-error, non-shell |:!|) output. +/// +/// On execution error: fails with VimL error, does not update v:errmsg. +/// +/// @see |execute()| +/// @see |nvim_command()| +/// +/// @param src Vimscript code +/// @param output Capture and return all (non-error, non-shell |:!|) output +/// @param[out] err Error details (Vim error), if any +String nvim_exec(String src, Boolean output, Error *err) + FUNC_API_SINCE(7) +{ + if (!output) { + try_start(); + do_source_str(src.data, "nvim_exec()"); + try_end(err); + return (String)STRING_INIT; + } + + const int save_msg_silent = msg_silent; + garray_T *const save_capture_ga = capture_ga; + garray_T capture_local; + ga_init(&capture_local, 1, 80); + + try_start(); + msg_silent++; + capture_ga = &capture_local; + do_source_str(src.data, "nvim_exec()"); + capture_ga = save_capture_ga; + msg_silent = save_msg_silent; + try_end(err); + + if (ERROR_SET(err)) { + goto theend; + } + + if (capture_local.ga_len > 1) { + String s = (String){ + .data = capture_local.ga_data, + .size = (size_t)capture_local.ga_len, + }; + // redir usually (except :echon) prepends a newline. + if (s.data[0] == '\n') { + memmove(s.data, s.data + 1, s.size - 1); + s.data[s.size - 1] = '\0'; + s.size = s.size - 1; + } + return s; // Caller will free the memory. + } +theend: + ga_clear(&capture_local); + return (String)STRING_INIT; +} + /// Executes an ex-command. /// /// On execution error: fails with VimL error, does not update v:errmsg. /// +/// @see |nvim_exec()| +/// /// @param command Ex-command string /// @param[out] err Error details (Vim error), if any void nvim_command(String command, Error *err) @@ -378,7 +439,7 @@ theend: return (String)STRING_INIT; } -/// Evaluates a VimL expression (:help expression). +/// Evaluates a VimL |expression|. /// Dictionaries and Lists are recursively expanded. /// /// On execution error: fails with VimL error, does not update v:errmsg. |