aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/window.c4
-rw-r--r--src/nvim/auevents.lua3
-rw-r--r--src/nvim/buffer.c18
-rw-r--r--src/nvim/ex_cmds2.c10
-rw-r--r--src/nvim/getchar.c27
-rw-r--r--src/nvim/log.c21
-rw-r--r--src/nvim/map.c12
-rw-r--r--src/nvim/normal.c1
-rw-r--r--src/nvim/terminal.c14
-rw-r--r--src/nvim/testdir/test_arglist.vim12
-rw-r--r--src/nvim/testdir/test_command_count.vim1
-rw-r--r--src/nvim/testdir/test_quickfix.vim14
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