aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_getln.c3
-rw-r--r--src/nvim/insexpand.c24
-rw-r--r--src/nvim/move.c1
3 files changed, 24 insertions, 4 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 6af79bfd21..c401293ccc 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4572,7 +4572,8 @@ static int open_cmdwin(void)
ccline.cmdlen = (int)strlen(ccline.cmdbuff);
ccline.cmdbufflen = ccline.cmdlen + 1;
ccline.cmdpos = curwin->w_cursor.col;
- if (ccline.cmdpos > ccline.cmdlen) {
+ // If the cursor is on the last character, it probably should be after it.
+ if (ccline.cmdpos == ccline.cmdlen - 1 || ccline.cmdpos > ccline.cmdlen) {
ccline.cmdpos = ccline.cmdlen;
}
if (cmdwin_result == K_IGNORE) {
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 8285c0c2b8..1a77679abd 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -64,6 +64,7 @@
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/vim.h"
+#include "nvim/window.h"
// Definitions used for CTRL-X submode.
// Note: If you change CTRL-X submode, you must also maintain ctrl_x_msgs[]
@@ -161,7 +162,8 @@ struct compl_S {
/// state information used for getting the next set of insert completion
/// matches.
typedef struct {
- char *e_cpt; ///< current entry in 'complete'
+ char *e_cpt_copy; ///< copy of 'complete'
+ char *e_cpt; ///< current entry in "e_cpt_copy"
buf_T *ins_buf; ///< buffer being scanned
pos_T *cur_match_pos; ///< current match position
pos_T prev_match_pos; ///< previous match position
@@ -2219,7 +2221,8 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
static win_T *wp = NULL;
if (flag == 'w') { // just windows
- if (buf == curbuf || wp == NULL) { // first call for this flag/expansion
+ if (buf == curbuf || !win_valid(wp)) {
+ // first call for this flag/expansion or window was closed
wp = curwin;
}
assert(wp);
@@ -3287,6 +3290,7 @@ static bool get_next_completion_match(int type, ins_compl_next_state_T *st, pos_
static int ins_compl_get_exp(pos_T *ini)
{
static ins_compl_next_state_T st;
+ static bool st_cleared = false;
int i;
int found_new_match;
int type = ctrl_x_mode;
@@ -3297,9 +3301,16 @@ static int ins_compl_get_exp(pos_T *ini)
FOR_ALL_BUFFERS(buf) {
buf->b_scanned = false;
}
+ if (!st_cleared) {
+ CLEAR_FIELD(st);
+ st_cleared = true;
+ }
st.found_all = false;
st.ins_buf = curbuf;
- st.e_cpt = (compl_cont_status & CONT_LOCAL) ? "." : curbuf->b_p_cpt;
+ xfree(st.e_cpt_copy);
+ // Make a copy of 'complete', in case the buffer is wiped out.
+ st.e_cpt_copy = xstrdup((compl_cont_status & CONT_LOCAL) ? "." : curbuf->b_p_cpt);
+ st.e_cpt = st.e_cpt_copy == NULL ? "" : st.e_cpt_copy;
st.last_match_pos = st.first_match_pos = *ini;
} else if (st.ins_buf != curbuf && !buf_valid(st.ins_buf)) {
st.ins_buf = curbuf; // In case the buffer was wiped out.
@@ -3599,6 +3610,7 @@ static int ins_compl_next(bool allow_get_expansion, int count, bool insert_match
int num_matches = -1;
int todo = count;
const bool started = compl_started;
+ buf_T *const orig_curbuf = curbuf;
// When user complete function return -1 for findstart which is next
// time of 'always', compl_shown_match become NULL.
@@ -3634,6 +3646,12 @@ static int ins_compl_next(bool allow_get_expansion, int count, bool insert_match
return -1;
}
+ if (curbuf != orig_curbuf) {
+ // In case some completion function switched buffer, don't want to
+ // insert the completion elsewhere.
+ return -1;
+ }
+
// Insert the text of the new completion, or the compl_leader.
if (compl_no_insert && !started) {
ins_bytes(compl_orig_text + get_compl_len());
diff --git a/src/nvim/move.c b/src/nvim/move.c
index faa491826a..3f4ba3c811 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -622,6 +622,7 @@ int cursor_valid(void)
// w_topline must be valid, you may need to call update_topline() first!
void validate_cursor(void)
{
+ check_cursor();
check_cursor_moved(curwin);
if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) {
curs_columns(curwin, true);