aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/extmark.c3
-rw-r--r--src/nvim/buffer_defs.h2
-rw-r--r--src/nvim/decoration.c12
-rw-r--r--src/nvim/drawline.c12
-rw-r--r--src/nvim/drawscreen.c2
-rw-r--r--src/nvim/eval.lua4
-rw-r--r--src/nvim/ex_docmd.c27
-rw-r--r--src/nvim/extmark.c14
-rw-r--r--src/nvim/insexpand.c4
-rw-r--r--src/nvim/mapping.c10
-rw-r--r--src/nvim/options.lua2
-rw-r--r--src/nvim/path.c34
-rw-r--r--src/nvim/tui/tui.c2
-rw-r--r--src/nvim/ui_defs.h4
14 files changed, 77 insertions, 55 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index fa74d9a667..5420816726 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -455,8 +455,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// otherwise the same as "trunc".
/// - ephemeral : for use with |nvim_set_decoration_provider()|
/// callbacks. The mark will only be used for the current
-/// redraw cycle, and not be permantently stored in the
-/// buffer.
+/// redraw cycle, and not be permanently stored in the buffer.
/// - right_gravity : boolean that indicates the direction
/// the extmark will be shifted in when new text is inserted
/// (true for right, false for left). Defaults to true.
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 87d548bfab..843eb5aa11 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -916,7 +916,7 @@ typedef enum {
typedef enum {
kWinStyleUnused = 0,
- kWinStyleMinimal, /// Minimal UI: no number column, eob markers, etc
+ kWinStyleMinimal, ///< Minimal UI: no number column, eob markers, etc
} WinStyle;
typedef enum {
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 1226bba436..a7339772ae 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -182,8 +182,9 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item)
void buf_put_decor(buf_T *buf, DecorInline decor, int row, int row2)
{
- if (decor.ext) {
+ if (decor.ext && row < buf->b_ml.ml_line_count) {
uint32_t idx = decor.data.ext.sh_idx;
+ row2 = MIN(buf->b_ml.ml_line_count - 1, row2);
while (idx != DECOR_ID_INVALID) {
DecorSignHighlight *sh = &kv_A(decor_items, idx);
buf_put_decor_sh(buf, sh, row, row2);
@@ -222,16 +223,17 @@ void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2)
void buf_decor_remove(buf_T *buf, int row1, int row2, int col1, DecorInline decor, bool free)
{
decor_redraw(buf, row1, row2, col1, decor);
- if (decor.ext) {
+ if (decor.ext && row1 < buf->b_ml.ml_line_count) {
uint32_t idx = decor.data.ext.sh_idx;
+ row2 = MIN(buf->b_ml.ml_line_count - 1, row2);
while (idx != DECOR_ID_INVALID) {
DecorSignHighlight *sh = &kv_A(decor_items, idx);
buf_remove_decor_sh(buf, row1, row2, sh);
idx = sh->next;
}
- if (free) {
- decor_free(decor);
- }
+ }
+ if (free) {
+ decor_free(decor);
}
}
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 9e65abe3e4..16e3a95121 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -664,11 +664,15 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv)
}
/// Build and draw the 'statuscolumn' string for line "lnum" in window "wp".
-static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int virtnum, int col_rows,
+static void draw_statuscol(win_T *wp, winlinevars_T *wlv, int virtnum, int col_rows,
statuscol_T *stcp)
{
- // When called for the first non-filler row of line "lnum" set num v:vars
- linenr_T relnum = virtnum == 0 ? abs(get_cursor_rel_lnum(wp, lnum)) : -1;
+ // Adjust lnum for filler lines belonging to the line above and set lnum v:vars for first
+ // row, first non-filler line, and first filler line belonging to the current line.
+ linenr_T lnum = wlv->lnum - ((wlv->n_virt_lines - wlv->filler_todo) < wlv->n_virt_below);
+ linenr_T relnum = (virtnum == -wlv->filler_lines || virtnum == 0
+ || virtnum == (wlv->n_virt_below - wlv->filler_lines))
+ ? abs(get_cursor_rel_lnum(wp, lnum)) : -1;
char buf[MAXPATHL];
// When a buffer's line count has changed, make a best estimate for the full
@@ -1639,7 +1643,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
} else if (statuscol.draw) {
// Draw 'statuscolumn' if it is set.
const int v = (int)(ptr - line);
- draw_statuscol(wp, &wlv, lnum, wlv.row - startrow - wlv.filler_lines, col_rows, &statuscol);
+ draw_statuscol(wp, &wlv, wlv.row - startrow - wlv.filler_lines, col_rows, &statuscol);
if (wp->w_redr_statuscol) {
break;
}
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index e958610f20..35dcbf295b 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -1238,7 +1238,7 @@ static bool win_redraw_signcols(win_T *wp)
if (!buf->b_signcols.autom
&& (*wp->w_p_stc != NUL || (wp->w_maxscwidth > 1 && wp->w_minscwidth != wp->w_maxscwidth))) {
buf->b_signcols.autom = true;
- buf_signcols_count_range(buf, 0, buf->b_ml.ml_line_count, MAXLNUM, kFalse);
+ buf_signcols_count_range(buf, 0, buf->b_ml.ml_line_count - 1, MAXLNUM, kFalse);
}
while (buf->b_signcols.max > 0 && buf->b_signcols.count[buf->b_signcols.max - 1] == 0) {
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index eb3956d155..d29c96a763 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -7200,7 +7200,7 @@ M.funcs = {
<results in `['two one']`.
]=],
name = 'matchfuzzy',
- params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'string' } },
+ params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'table' } },
signature = 'matchfuzzy({list}, {str} [, {dict}])',
},
matchfuzzypos = {
@@ -7229,7 +7229,7 @@ M.funcs = {
<results in `[[{"id": 10, "text": "hello"}], [[2, 3]], [127]]`
]=],
name = 'matchfuzzypos',
- params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'string' } },
+ params = { { 'list', 'any[]' }, { 'str', 'string' }, { 'dict', 'table' } },
signature = 'matchfuzzypos({list}, {str} [, {dict}])',
},
matchlist = {
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 3b78092daf..af93db9956 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -406,6 +406,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
bool msg_didout_before_start = false;
int count = 0; // line number count
bool did_inc = false; // incremented RedrawingDisabled
+ int block_indent = -1; // indent for ext_cmdline block event
int retval = OK;
cstack_T cstack = { // conditional stack
.cs_idx = -1,
@@ -573,16 +574,18 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// 2. If no line given, get an allocated line with fgetline().
if (next_cmdline == NULL) {
- // Need to set msg_didout for the first line after an ":if",
- // otherwise the ":if" will be overwritten.
- if (count == 1 && getline_equal(fgetline, cookie, getexline)) {
- msg_didout = true;
- }
- if (fgetline == NULL
- || (next_cmdline = fgetline(':', cookie,
- cstack.cs_idx <
- 0 ? 0 : (cstack.cs_idx + 1) * 2,
- true)) == NULL) {
+ int indent = cstack.cs_idx < 0 ? 0 : (cstack.cs_idx + 1) * 2;
+ if (count >= 1 && getline_equal(fgetline, cookie, getexline)) {
+ if (ui_has(kUICmdline)) {
+ ui_ext_cmdline_block_append((size_t)MAX(0, block_indent), last_cmdline);
+ block_indent = indent;
+ } else if (count == 1) {
+ // Need to set msg_didout for the first line after an ":if",
+ // otherwise the ":if" will be overwritten.
+ msg_didout = true;
+ }
+ }
+ if (fgetline == NULL || (next_cmdline = fgetline(':', cookie, indent, true)) == NULL) {
// Don't call wait_return() for aborted command line. The NULL
// returned for the end of a sourced file or executed function
// doesn't do this.
@@ -939,6 +942,10 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
}
}
+ if (block_indent >= 0) {
+ ui_ext_cmdline_block_leave();
+ }
+
did_endif = false; // in case do_cmdline used recursively
do_cmdline_end();
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 7e6dfb8dea..cad0f71941 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -135,7 +135,7 @@ static void extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col, bool
} else if (!mt_invalid(key) && key.flags & MT_FLAG_DECOR_SIGNTEXT && buf->b_signcols.autom) {
row1 = MIN(alt.pos.row, MIN(key.pos.row, row));
row2 = MAX(alt.pos.row, MAX(key.pos.row, row));
- buf_signcols_count_range(buf, row1, row2, 0, kTrue);
+ buf_signcols_count_range(buf, row1, MIN(curbuf->b_ml.ml_line_count - 1, row2), 0, kTrue);
}
if (move) {
@@ -145,7 +145,7 @@ static void extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col, bool
if (invalid) {
buf_put_decor(buf, mt_decor(key), MIN(row, key.pos.row), MAX(row, key.pos.row));
} else if (!mt_invalid(key) && key.flags & MT_FLAG_DECOR_SIGNTEXT && buf->b_signcols.autom) {
- buf_signcols_count_range(buf, row1, row2, 0, kNone);
+ buf_signcols_count_range(buf, row1, MIN(curbuf->b_ml.ml_line_count - 1, row2), 0, kNone);
}
}
@@ -180,7 +180,9 @@ void extmark_del(buf_T *buf, MarkTreeIter *itr, MTKey key, bool restore)
}
if (mt_decor_any(key)) {
- if (mt_invalid(key)) {
+ // If key is an end mark it has been found first while iterating the marktree,
+ // indicating the decor is already invalid.
+ if (mt_invalid(key) || mt_end(key)) {
decor_free(mt_decor(key));
} else {
buf_decor_remove(buf, key.pos.row, key2.pos.row, key.pos.col, mt_decor(key), true);
@@ -575,7 +577,8 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t
// Remove signs inside edited region from "b_signcols.count", add after splicing.
if (old_row > 0 || new_row > 0) {
- buf_signcols_count_range(buf, start_row, start_row + old_row, 0, kTrue);
+ int row2 = MIN(buf->b_ml.ml_line_count - (new_row - old_row) - 1, start_row + old_row);
+ buf_signcols_count_range(buf, start_row, row2, 0, kTrue);
}
marktree_splice(buf->b_marktree, (int32_t)start_row, start_col,
@@ -583,7 +586,8 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t
new_row, new_col);
if (old_row > 0 || new_row > 0) {
- buf_signcols_count_range(buf, start_row, start_row + new_row, 0, kNone);
+ int row2 = MIN(buf->b_ml.ml_line_count - 1, start_row + new_row);
+ buf_signcols_count_range(buf, start_row, row2, 0, kNone);
}
if (undo == kExtmarkUndo) {
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index d02a698f08..1be4f601bc 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -2169,6 +2169,10 @@ static bool set_ctrl_x_mode(const int c)
/// Stop insert completion mode
static bool ins_compl_stop(const int c, const int prev_mode, bool retval)
{
+ // Remove pre-inserted text when present.
+ if (ins_compl_preinsert_effect()) {
+ ins_compl_delete(false);
+ }
// Get here when we have finished typing a sequence of ^N and
// ^P or other completion characters in CTRL-X mode. Free up
// memory that was used, and make sure we can redo the insert.
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index ca0349d1f6..2b9a972bc9 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -104,14 +104,14 @@ struct map_arguments {
char alt_lhs[MAXMAPLEN + 1];
size_t alt_lhs_len;
- char *rhs; /// The {rhs} of the mapping.
+ char *rhs; ///< The {rhs} of the mapping.
size_t rhs_len;
- LuaRef rhs_lua; /// lua function as {rhs}
- bool rhs_is_noop; /// True when the {rhs} should be <Nop>.
+ LuaRef rhs_lua; ///< lua function as {rhs}
+ bool rhs_is_noop; ///< True when the {rhs} should be <Nop>.
- char *orig_rhs; /// The original text of the {rhs}.
+ char *orig_rhs; ///< The original text of the {rhs}.
size_t orig_rhs_len;
- char *desc; /// map description
+ char *desc; ///< map description
};
typedef struct map_arguments MapArguments;
#define MAP_ARGUMENTS_INIT { false, false, false, false, false, false, false, false, \
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 49de8b92ef..e9f8051ed3 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1483,7 +1483,7 @@ local options = {
{
abbreviation = 'cot',
cb = 'did_set_completeopt',
- defaults = 'menu,preview',
+ defaults = 'menu,popup',
values = {
'menu',
'menuone',
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 6c6a6f58c0..fd2b92e30d 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -613,7 +613,6 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
FUNC_ATTR_NONNULL_ALL
{
int start_len = gap->ga_len;
- size_t len;
bool starstar = false;
static int stardepth = 0; // depth for "**" expansion
@@ -625,9 +624,9 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
}
}
- // Make room for file name. When doing encoding conversion the actual
- // length may be quite a bit longer, thus use the maximum possible length.
- char *buf = xmalloc(MAXPATHL);
+ // Make room for file name (a bit too much to stay on the safe side).
+ const size_t buflen = strlen(path) + MAXPATHL;
+ char *buf = xmalloc(buflen);
// Find the first part in the path name that contains a wildcard.
// When EW_ICASE is set every letter is considered to be a wildcard.
@@ -656,10 +655,10 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
) {
e = p;
}
- len = (size_t)(utfc_ptr2len(path_end));
- memcpy(p, path_end, len);
- p += len;
- path_end += len;
+ int charlen = utfc_ptr2len(path_end);
+ memcpy(p, path_end, (size_t)charlen);
+ p += charlen;
+ path_end += charlen;
}
e = p;
*e = NUL;
@@ -713,13 +712,14 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
return 0;
}
+ size_t len = (size_t)(s - buf);
// If "**" is by itself, this is the first time we encounter it and more
// is following then find matches without any directory.
if (!didstar && stardepth < 100 && starstar && e - s == 2
&& *path_end == '/') {
- STRCPY(s, path_end + 1);
+ vim_snprintf(s, buflen - len, "%s", path_end + 1);
stardepth++;
- do_path_expand(gap, buf, (size_t)(s - buf), flags, true);
+ do_path_expand(gap, buf, len, flags, true);
stardepth--;
}
*s = NUL;
@@ -731,6 +731,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
const char *name;
scandir_next_with_dots(NULL); // initialize
while (!got_int && (name = scandir_next_with_dots(&dir)) != NULL) {
+ len = (size_t)(s - buf);
if ((name[0] != '.'
|| starts_with_dot
|| ((flags & EW_DODOT)
@@ -738,21 +739,22 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
&& (name[1] != '.' || name[2] != NUL)))
&& ((regmatch.regprog != NULL && vim_regexec(&regmatch, name, 0))
|| ((flags & EW_NOTWILD)
- && path_fnamencmp(path + (s - buf), name, (size_t)(e - s)) == 0))) {
- STRCPY(s, name);
- len = strlen(buf);
+ && path_fnamencmp(path + len, name, (size_t)(e - s)) == 0))) {
+ len += (size_t)vim_snprintf(s, buflen - len, "%s", name);
+ if (len + 1 >= buflen) {
+ continue;
+ }
if (starstar && stardepth < 100) {
// For "**" in the pattern first go deeper in the tree to
// find matches.
- STRCPY(buf + len, "/**"); // NOLINT
- STRCPY(buf + len + 3, path_end);
+ vim_snprintf(buf + len, buflen - len, "/**%s", path_end); // NOLINT
stardepth++;
do_path_expand(gap, buf, len + 1, flags, true);
stardepth--;
}
- STRCPY(buf + len, path_end);
+ vim_snprintf(buf + len, buflen - len, "%s", path_end);
if (path_has_exp_wildcard(path_end)) { // handle more wildcards
// need to expand another component of the path
// remove backslashes for the remaining components only
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 7c93be844a..440747be76 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -299,7 +299,7 @@ void tui_set_key_encoding(TUIData *tui)
// Progressive enhancement flags:
// 0b01 (1) Disambiguate escape codes
// 0b10 (2) Report event types
- out(tui, S_LEN("\x1b[>3u"));
+ out(tui, S_LEN("\x1b[>1u"));
break;
case kKeyEncodingXterm:
out(tui, S_LEN("\x1b[>4;2m"));
diff --git a/src/nvim/ui_defs.h b/src/nvim/ui_defs.h
index bbc1655252..b140eee2c5 100644
--- a/src/nvim/ui_defs.h
+++ b/src/nvim/ui_defs.h
@@ -37,8 +37,8 @@ typedef struct {
bool ui_ext[kUIExtCount]; ///< Externalized UI capabilities.
int width;
int height;
- int pum_nlines; /// actual nr. lines shown in PUM
- bool pum_pos; /// UI reports back pum position?
+ int pum_nlines; ///< actual nr. lines shown in PUM
+ bool pum_pos; ///< UI reports back pum position?
double pum_row;
double pum_col;
double pum_height;