diff options
-rw-r--r-- | src/nvim/api/vim.c | 63 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 26 |
3 files changed, 39 insertions, 52 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index bf73a721fb..1ca0d8789d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -54,6 +54,20 @@ # include "api/vim.c.generated.h" #endif +// `msg_list` controls the collection of abort-causing non-exception errors, +// which would otherwise be ignored. This pattern is from do_cmdline(). +// +// TODO(bfredl): prepare error-handling at "top level" (nv_event). +#define TRY_WRAP(code) \ + do { \ + struct msglist **saved_msg_list = msg_list; \ + struct msglist *private_msg_list; \ + msg_list = &private_msg_list; \ + private_msg_list = NULL; \ + code \ + msg_list = saved_msg_list; /* Restore the exception context. */ \ + } while (0) + void api_vim_init(void) FUNC_API_NOEXPORT { @@ -392,13 +406,7 @@ Object nvim_eval(String expr, Error *err) static int recursive = 0; // recursion depth Object rv = OBJECT_INIT; - // `msg_list` controls the collection of abort-causing non-exception errors, - // which would otherwise be ignored. This pattern is from do_cmdline(). - struct msglist **saved_msg_list = msg_list; - struct msglist *private_msg_list; - msg_list = &private_msg_list; - private_msg_list = NULL; - + TRY_WRAP({ // Initialize `force_abort` and `suppress_errthrow` at the top level. if (!recursive) { force_abort = false; @@ -423,8 +431,8 @@ Object nvim_eval(String expr, Error *err) } tv_clear(&rettv); - msg_list = saved_msg_list; // Restore the exception context. recursive--; + }); return rv; } @@ -474,13 +482,7 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) } } - // `msg_list` controls the collection of abort-causing non-exception errors, - // which would otherwise be ignored. This pattern is from do_cmdline(). - struct msglist **saved_msg_list = msg_list; - struct msglist *private_msg_list; - msg_list = &private_msg_list; - private_msg_list = NULL; - + TRY_WRAP({ // Initialize `force_abort` and `suppress_errthrow` at the top level. if (!recursive) { force_abort = false; @@ -502,8 +504,8 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) rv = vim_to_object(&rettv); } tv_clear(&rettv); - msg_list = saved_msg_list; // Restore the exception context. recursive--; + }); free_vim_args: while (i > 0) { @@ -1238,7 +1240,6 @@ Boolean nvim_paste(String data, Integer phase, Error *err) return false; } Array args = ARRAY_DICT_INIT; - Array args2 = ARRAY_DICT_INIT; Object rv = OBJECT_INIT; if (phase == -1 || phase == 1) { // Start of paste-stream. draining = false; @@ -1249,9 +1250,8 @@ Boolean nvim_paste(String data, Integer phase, Error *err) Array lines = string_to_array(data); ADD(args, ARRAY_OBJ(lines)); ADD(args, INTEGER_OBJ(phase)); - ADD(args2, STRING_OBJ(cstr_to_string("vim.paste(_A[1], _A[2])"))); - ADD(args2, ARRAY_OBJ(args2)); - rv = nvim_call_function(STATIC_CSTR_AS_STRING("luaeval"), args2, err); + rv = nvim_execute_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args, + err); if (ERROR_SET(err)) { draining = true; goto theend; @@ -1278,7 +1278,8 @@ Boolean nvim_paste(String data, Integer phase, Error *err) AppendCharToRedobuff(ESC); // Dot-repeat. } theend: - api_free_array(args2); + api_free_object(rv); + api_free_array(args); if (cancel || phase == -1 || phase == 3) { // End of paste-stream. draining = false; // XXX: Tickle main loop to ensure cursor is updated. @@ -1310,10 +1311,6 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, api_set_error(err, kErrorTypeValidation, "Invalid type: '%s'", type.data); goto cleanup; } - if (!MODIFIABLE(curbuf)) { - api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); - goto cleanup; - } if (lines.size == 0) { goto cleanup; // Nothing to do. } @@ -1331,13 +1328,15 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, finish_yankreg_from_object(reg, false); - bool VIsual_was_active = VIsual_active; - msg_silent++; // Avoid "N more lines" message. - do_put(0, reg, - after ? FORWARD : BACKWARD, 1, - follow ? PUT_CURSEND : 0); - msg_silent--; - VIsual_active = VIsual_was_active; + TRY_WRAP({ + try_start(); + bool VIsual_was_active = VIsual_active; + msg_silent++; // Avoid "N more lines" message. + do_put(0, reg, after ? FORWARD : BACKWARD, 1, follow ? PUT_CURSEND : 0); + msg_silent--; + VIsual_active = VIsual_was_active; + try_end(err); + }); cleanup: free_register(reg); diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 884e07e2c5..647fab5c43 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -411,7 +411,7 @@ describe('API', function() end) it("fails if 'nomodifiable'", function() command('set nomodifiable') - expect_err([[Buffer is not 'modifiable']], request, + expect_err([[Vim:E21: Cannot make changes, 'modifiable' is off]], request, 'nvim_put', {'a','b'}, 'l', true, true) end) it('inserts text', function() diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 7435b293fd..5445ff0127 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -185,6 +185,7 @@ describe('TUI', function() {3:-- TERMINAL --} | ]]) feed_data('pasted from terminal') + expect_child_buf_lines({'"pasted from terminal"'}) screen:expect([[ "pasted from terminal{1:"} | {4:~ }| @@ -196,6 +197,7 @@ describe('TUI', function() ]]) feed_data('\027[201~') -- End paste. feed_data('\027\000') -- ESC: go to Normal mode. + wait_for_mode('n') screen:expect([[ "pasted from termina{1:l}" | {4:~ }| @@ -207,6 +209,8 @@ describe('TUI', function() ]]) -- Dot-repeat/redo. feed_data('2.') + expect_child_buf_lines( + {'"pasted from terminapasted from terminalpasted from terminall"'}) screen:expect([[ "pasted from terminapasted from terminalpasted fro| m termina{1:l}l" | @@ -341,18 +345,10 @@ describe('TUI', function() | {3:-- TERMINAL --} | ]]} - wait_for_mode('n') -- Start pasting... feed_data('\027[200~line 1\nline 2\n') - screen:expect{grid=[[ - foo | - | - {4:~ }| - {5: }| - {8:paste: Vim:E5108: Error while calling lua chunk fo}| - {10:Press ENTER or type command to continue}{1: } | - {3:-- TERMINAL --} | - ]]} + wait_for_mode('n') + screen:expect{any='paste: Error executing lua'} -- Remaining chunks are discarded after vim.paste() failure. feed_data('line 3\nline 4\n') feed_data('line 5\nline 6\n') @@ -402,15 +398,7 @@ describe('TUI', function() it("paste: 'nomodifiable' buffer", function() child_session:request('nvim_command', 'set nomodifiable') feed_data('\027[200~fail 1\nfail 2\n\027[201~') - screen:expect{grid=[[ - | - {5: }| - {8:paste: Vim:E5108: Error while calling lua chunk fo}| - {8:r luaeval(): [string "-- Nvim-Lua stdlib: the `vim}| - {8:` module (:help l..."]:193: Buffer is not 'modifia}| - {10:Press ENTER or type command to continue}{1: } | - {3:-- TERMINAL --} | - ]]} + screen:expect{any='Vim:E21'} feed_data('\n') -- <Enter> child_session:request('nvim_command', 'set modifiable') feed_data('\027[200~success 1\nsuccess 2\n\027[201~') |