diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/window.c | 4 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 3 | ||||
-rw-r--r-- | src/nvim/buffer.c | 18 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 10 | ||||
-rw-r--r-- | src/nvim/getchar.c | 27 | ||||
-rw-r--r-- | src/nvim/log.c | 21 | ||||
-rw-r--r-- | src/nvim/map.c | 12 | ||||
-rw-r--r-- | src/nvim/normal.c | 1 | ||||
-rw-r--r-- | src/nvim/terminal.c | 14 | ||||
-rw-r--r-- | src/nvim/testdir/test_arglist.vim | 12 | ||||
-rw-r--r-- | src/nvim/testdir/test_command_count.vim | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_quickfix.vim | 14 |
12 files changed, 105 insertions, 32 deletions
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index a68ae805e8..01cb9a6847 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -67,6 +67,10 @@ void nvim_win_set_buf(Window window, Buffer buffer, Error *err) buffer); } + // If window is not current, state logic will not validate its cursor. + // So do it now. + validate_cursor(); + restore_win(save_curwin, save_curtab, false); } diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index 32a7920b6e..ef528f72b8 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -65,7 +65,6 @@ return { 'InsertCharPre', -- before inserting a char 'InsertEnter', -- when entering Insert mode 'InsertLeave', -- when leaving Insert mode - 'JobActivity', -- when job sent some data 'MenuPopup', -- just before popup menu is displayed 'OptionSet', -- after setting any option 'QuickFixCmdPost', -- after :make, :grep etc. @@ -89,7 +88,7 @@ return { 'TabNew', -- when creating a new tab 'TabNewEntered', -- after entering a new tab 'TermChanged', -- after changing 'term' - 'TermClose', -- after the processs exits + 'TermClose', -- after the process exits 'TermOpen', -- after opening a terminal buffer 'TermResponse', -- after setting "v:termresponse" 'TextChanged', -- text was modified diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8d075dfeae..703a89d31f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1717,11 +1717,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) * buffer.) */ buf = NULL; - if ((flags & BLN_CURBUF) - && curbuf != NULL - && curbuf->b_ffname == NULL - && curbuf->b_nwindows <= 1 - && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY())) { + if ((flags & BLN_CURBUF) && curbuf_reusable()) { buf = curbuf; /* It's like this buffer is deleted. Watch out for autocommands that * change curbuf! If that happens, allocate a new buffer anyway. */ @@ -1864,6 +1860,18 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) return buf; } +/// Return true if the current buffer is empty, unnamed, unmodified and used in +/// only one window. That means it can be reused. +bool curbuf_reusable(void) +{ + return (curbuf != NULL + && curbuf->b_ffname == NULL + && curbuf->b_nwindows <= 1 + && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY()) + && !bt_quickfix(curbuf) + && !curbufIsChanged()); +} + /* * Free the memory for the options of a buffer. * If "free_p_ff" is true also free 'fileformat', 'buftype' and diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 4684a1b31d..15b735dc9e 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1952,14 +1952,17 @@ void ex_next(exarg_T *eap) void ex_argedit(exarg_T *eap) { int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1; + // Whether curbuf will be reused, curbuf->b_ffname will be set. + bool curbuf_is_reusable = curbuf_reusable(); if (do_arglist(eap->arg, AL_ADD, i) == FAIL) { return; } maketitle(); - if (curwin->w_arg_idx == 0 && (curbuf->b_ml.ml_flags & ML_EMPTY) - && curbuf->b_ffname == NULL) { + if (curwin->w_arg_idx == 0 + && (curbuf->b_ml.ml_flags & ML_EMPTY) + && (curbuf->b_ffname == NULL || curbuf_is_reusable)) { i = 0; } // Edit the argument. @@ -2257,7 +2260,8 @@ static int alist_add_list(int count, char_u **files, int after) } for (int i = 0; i < count; i++) { ARGLIST[after + i].ae_fname = files[i]; - ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED); + ARGLIST[after + i].ae_fnum = buflist_add(files[i], + BLN_LISTED | BLN_CURBUF); } ALIST(curwin)->al_ga.ga_len += count; if (old_argcount > 0 && curwin->w_arg_idx >= after) { diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index c29ef9f822..0020b57482 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2270,18 +2270,25 @@ static int vgetorpeek(int advance) // that has a <Nop> RHS. timedout = false; } + + long wait_time = 0; + + if (advance) { + if (typebuf.tb_len == 0 + || !(p_timeout || (p_ttimeout && keylen == KEYLEN_PART_KEY))) { + // blocking wait + wait_time = -1L; + } else if (keylen == KEYLEN_PART_KEY && p_ttm >= 0) { + wait_time = p_ttm; + } else { + wait_time = p_tm; + } + } + wait_tb_len = typebuf.tb_len; c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, - typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1, - !advance - ? 0 - : ((typebuf.tb_len == 0 - || !(p_timeout || (p_ttimeout - && keylen == KEYLEN_PART_KEY))) - ? -1L - : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0) - ? p_ttm - : p_tm))); + typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1, + wait_time); if (i != 0) pop_showcmd(); diff --git a/src/nvim/log.c b/src/nvim/log.c index 8066b6e828..a2f83d4d09 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -1,6 +1,13 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// +// Log module +// +// How Linux printk() handles recursion, buffering, etc: +// https://lwn.net/Articles/780556/ +// + #include <assert.h> #include <inttypes.h> #include <stdarg.h> @@ -99,9 +106,14 @@ void log_unlock(void) uv_mutex_unlock(&mutex); } -/// @param context description of a shared context or subsystem -/// @param func_name function name, or NULL -/// @param line_num source line number, or -1 +/// Logs a message to $NVIM_LOG_FILE. +/// +/// @param log_level Log level (see log.h) +/// @param context Description of a shared context or subsystem +/// @param func_name Function name, or NULL +/// @param line_num Source line number, or -1 +/// @param eol Append linefeed "\n" +/// @param fmt printf-style format string bool logmsg(int log_level, const char *context, const char *func_name, int line_num, bool eol, const char *fmt, ...) FUNC_ATTR_UNUSED FUNC_ATTR_PRINTF(6, 7) @@ -163,7 +175,8 @@ end: FILE *open_log_file(void) { static bool opening_log_file = false; - // check if it's a recursive call + // Disallow recursion. (This only matters for log_path_init; for logmsg and + // friends we use a mutex: log_lock). if (opening_log_file) { do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, "Cannot LOG() recursively."); diff --git a/src/nvim/map.c b/src/nvim/map.c index 9b6f57a56f..90da27cf9f 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -1,12 +1,12 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -/// -/// map.c: khash.h wrapper -/// -/// NOTE: Callers must manage memory (allocate) for keys and values. -/// khash.h does not make its own copy of the key or value. -/// +// +// map.c: khash.h wrapper +// +// NOTE: Callers must manage memory (allocate) for keys and values. +// khash.h does not make its own copy of the key or value. +// #include <stdlib.h> #include <stdbool.h> diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 8da64bf01b..abee28e37e 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -8001,7 +8001,6 @@ static void nv_event(cmdarg_T *cap) // lists or dicts being used. may_garbage_collect = false; multiqueue_process_events(main_loop.events); - cap->retval |= CA_COMMAND_BUSY; // don't call edit() now finish_op = false; } diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 43beb684da..79b0df842f 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -403,6 +403,7 @@ void terminal_enter(void) redraw(false); s->state.execute = terminal_execute; + s->state.check = terminal_check; state_enter(&s->state); restart_edit = 0; @@ -427,6 +428,19 @@ void terminal_enter(void) } } +// Function executed before each iteration of terminal mode. +// Return: +// 1 if the iteration should continue normally +// 0 if the main loop must exit +static int terminal_check(VimState *state) +{ + if (stop_insert_mode) { + stop_insert_mode = false; + return 0; + } + return 1; +} + static int terminal_execute(VimState *state, int key) { TerminalState *s = (TerminalState *)state; diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim index ae975fe137..3a9ffbdbf3 100644 --- a/src/nvim/testdir/test_arglist.vim +++ b/src/nvim/testdir/test_arglist.vim @@ -329,6 +329,18 @@ func Test_argedit() %argd bwipe! C bwipe! D + + " :argedit reuses the current buffer if it is empty + %argd + " make sure to use a new buffer number for x when it is loaded + bw! x + new + let a = bufnr('') + argedit x + call assert_equal(a, bufnr('')) + call assert_equal('x', bufname('')) + %argd + bw! x endfunc " Test for the :argdelete command diff --git a/src/nvim/testdir/test_command_count.vim b/src/nvim/testdir/test_command_count.vim index 2d793ed88f..7262789ab4 100644 --- a/src/nvim/testdir/test_command_count.vim +++ b/src/nvim/testdir/test_command_count.vim @@ -173,7 +173,6 @@ func Test_command_count_4() only! exe bufnr . 'buf' - bnext let bufnr = bufnr('%') let buffers = [] .,$-bufdo call add(buffers, bufnr('%')) diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index cb3e7ca8f6..6227095f4f 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2664,3 +2664,17 @@ func Test_qfwin_pos() call assert_equal(3, winnr()) close endfunc + +" Test to make sure that an empty quickfix buffer is not reused for loading +" a normal buffer. +func Test_empty_qfbuf() + enew | only + call writefile(["Test"], 'Xfile1') + call setqflist([], 'f') + copen | only + let qfbuf = bufnr('') + edit Xfile1 + call assert_notequal(qfbuf, bufnr('')) + enew + call delete('Xfile1') +endfunc |