aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/autocmd.c73
-rw-r--r--src/nvim/api/buffer.c14
-rw-r--r--src/nvim/api/command.c11
-rw-r--r--src/nvim/api/extmark.c38
-rw-r--r--src/nvim/api/vim.c32
-rw-r--r--src/nvim/api/win_config.c22
-rw-r--r--src/nvim/decoration.c39
-rw-r--r--src/nvim/decoration.h2
-rw-r--r--src/nvim/drawline.c69
-rw-r--r--src/nvim/edit.c5
-rw-r--r--src/nvim/eval.c46
-rw-r--r--src/nvim/eval.lua6
-rw-r--r--src/nvim/mapping.c158
-rw-r--r--src/nvim/marktree.c9
-rw-r--r--src/nvim/options.lua2
-rw-r--r--src/nvim/spell.c2
16 files changed, 272 insertions, 256 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index aa0c2695ad..2e4d2a622d 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -49,19 +49,20 @@ static int64_t next_autocmd_id = 1;
/// Get all autocommands that match the corresponding {opts}.
///
/// These examples will get autocommands matching ALL the given criteria:
-/// <pre>lua
-/// -- Matches all criteria
-/// autocommands = vim.api.nvim_get_autocmds({
-/// group = "MyGroup",
-/// event = {"BufEnter", "BufWinEnter"},
-/// pattern = {"*.c", "*.h"}
-/// })
///
-/// -- All commands from one group
-/// autocommands = vim.api.nvim_get_autocmds({
-/// group = "MyGroup",
-/// })
-/// </pre>
+/// ```lua
+/// -- Matches all criteria
+/// autocommands = vim.api.nvim_get_autocmds({
+/// group = "MyGroup",
+/// event = {"BufEnter", "BufWinEnter"},
+/// pattern = {"*.c", "*.h"}
+/// })
+///
+/// -- All commands from one group
+/// autocommands = vim.api.nvim_get_autocmds({
+/// group = "MyGroup",
+/// })
+/// ```
///
/// NOTE: When multiple patterns or events are provided, it will find all the autocommands that
/// match any combination of them.
@@ -344,28 +345,31 @@ cleanup:
/// function _name_ string) or `command` (Ex command string).
///
/// Example using Lua callback:
-/// <pre>lua
-/// vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
-/// pattern = {"*.c", "*.h"},
-/// callback = function(ev)
-/// print(string.format('event fired: \%s', vim.inspect(ev)))
-/// end
-/// })
-/// </pre>
+///
+/// ```lua
+/// vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
+/// pattern = {"*.c", "*.h"},
+/// callback = function(ev)
+/// print(string.format('event fired: %s', vim.inspect(ev)))
+/// end
+/// })
+/// ```
///
/// Example using an Ex command as the handler:
-/// <pre>lua
-/// vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
-/// pattern = {"*.c", "*.h"},
-/// command = "echo 'Entering a C or C++ file'",
-/// })
-/// </pre>
+///
+/// ```lua
+/// vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
+/// pattern = {"*.c", "*.h"},
+/// command = "echo 'Entering a C or C++ file'",
+/// })
+/// ```
///
/// Note: `pattern` is NOT automatically expanded (unlike with |:autocmd|), thus names like "$HOME"
/// and "~" must be expanded explicitly:
-/// <pre>lua
-/// pattern = vim.fn.expand("~") .. "/some/path/*.py"
-/// </pre>
+///
+/// ```lua
+/// pattern = vim.fn.expand("~") .. "/some/path/*.py"
+/// ```
///
/// @param event (string|array) Event(s) that will trigger the handler (`callback` or `command`).
/// @param opts Options dict:
@@ -619,11 +623,12 @@ cleanup:
/// Create or get an autocommand group |autocmd-groups|.
///
/// To get an existing group id, do:
-/// <pre>lua
-/// local id = vim.api.nvim_create_augroup("MyGroup", {
-/// clear = false
-/// })
-/// </pre>
+///
+/// ```lua
+/// local id = vim.api.nvim_create_augroup("MyGroup", {
+/// clear = false
+/// })
+/// ```
///
/// @param name String: The name of the group
/// @param opts Dictionary Parameters
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index baac694848..e8f9f809f2 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -85,11 +85,15 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err)
///
/// Example (Lua): capture buffer updates in a global `events` variable
/// (use "vim.print(events)" to see its contents):
-/// <pre>lua
-/// events = {}
-/// vim.api.nvim_buf_attach(0, false, {
-/// on_lines=function(...) table.insert(events, {...}) end})
-/// </pre>
+///
+/// ```lua
+/// events = {}
+/// vim.api.nvim_buf_attach(0, false, {
+/// on_lines = function(...)
+/// table.insert(events, {...})
+/// end,
+/// })
+/// ```
///
/// @see |nvim_buf_detach()|
/// @see |api-buffer-updates-lua|
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index 2b09cfc4b2..808d4e0b8d 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -860,11 +860,12 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin
/// For Lua usage see |lua-guide-commands-create|.
///
/// Example:
-/// <pre>vim
-/// :call nvim_create_user_command('SayHello', 'echo "Hello world!"', {'bang': v:true})
-/// :SayHello
-/// Hello world!
-/// </pre>
+///
+/// ```vim
+/// :call nvim_create_user_command('SayHello', 'echo "Hello world!"', {'bang': v:true})
+/// :SayHello
+/// Hello world!
+/// ```
///
/// @param name Name of the new user command. Must begin with an uppercase letter.
/// @param command Replacement command to execute when this user command is executed. When called
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index b76a275c0d..05f62f6c7c 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -300,10 +300,11 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
/// Region can be given as (row,col) tuples, or valid extmark ids (whose
/// positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
/// respectively, thus the following are equivalent:
-/// <pre>lua
-/// vim.api.nvim_buf_get_extmarks(0, my_ns, 0, -1, {})
-/// vim.api.nvim_buf_get_extmarks(0, my_ns, {0,0}, {-1,-1}, {})
-/// </pre>
+///
+/// ```lua
+/// vim.api.nvim_buf_get_extmarks(0, my_ns, 0, -1, {})
+/// vim.api.nvim_buf_get_extmarks(0, my_ns, {0,0}, {-1,-1}, {})
+/// ```
///
/// If `end` is less than `start`, traversal works backwards. (Useful
/// with `limit`, to get the first marks prior to a given position.)
@@ -313,20 +314,21 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
/// of an extmark will be considered.
///
/// Example:
-/// <pre>lua
-/// local api = vim.api
-/// local pos = api.nvim_win_get_cursor(0)
-/// local ns = api.nvim_create_namespace('my-plugin')
-/// -- Create new extmark at line 1, column 1.
-/// local m1 = api.nvim_buf_set_extmark(0, ns, 0, 0, {})
-/// -- Create new extmark at line 3, column 1.
-/// local m2 = api.nvim_buf_set_extmark(0, ns, 2, 0, {})
-/// -- Get extmarks only from line 3.
-/// local ms = api.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {})
-/// -- Get all marks in this buffer + namespace.
-/// local all = api.nvim_buf_get_extmarks(0, ns, 0, -1, {})
-/// vim.print(ms)
-/// </pre>
+///
+/// ```lua
+/// local api = vim.api
+/// local pos = api.nvim_win_get_cursor(0)
+/// local ns = api.nvim_create_namespace('my-plugin')
+/// -- Create new extmark at line 1, column 1.
+/// local m1 = api.nvim_buf_set_extmark(0, ns, 0, 0, {})
+/// -- Create new extmark at line 3, column 1.
+/// local m2 = api.nvim_buf_set_extmark(0, ns, 2, 0, {})
+/// -- Get extmarks only from line 3.
+/// local ms = api.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {})
+/// -- Get all marks in this buffer + namespace.
+/// local all = api.nvim_buf_get_extmarks(0, ns, 0, -1, {})
+/// vim.print(ms)
+/// ```
///
/// @param buffer Buffer handle, or 0 for current buffer
/// @param ns_id Namespace id from |nvim_create_namespace()| or -1 for all namespaces
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index da10ab5bd4..916409b973 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -212,10 +212,11 @@ void nvim_set_hl_ns_fast(Integer ns_id, Error *err)
/// nvim_feedkeys().
///
/// Example:
-/// <pre>vim
-/// :let key = nvim_replace_termcodes("<C-o>", v:true, v:false, v:true)
-/// :call nvim_feedkeys(key, 'n', v:false)
-/// </pre>
+///
+/// ```vim
+/// :let key = nvim_replace_termcodes("<C-o>", v:true, v:false, v:true)
+/// :call nvim_feedkeys(key, 'n', v:false)
+/// ```
///
/// @param keys to be typed
/// @param mode behavior flags, see |feedkeys()|
@@ -1280,10 +1281,11 @@ void nvim_unsubscribe(uint64_t channel_id, String event)
/// "#rrggbb" hexadecimal string.
///
/// Example:
-/// <pre>vim
-/// :echo nvim_get_color_by_name("Pink")
-/// :echo nvim_get_color_by_name("#cbcbcb")
-/// </pre>
+///
+/// ```vim
+/// :echo nvim_get_color_by_name("Pink")
+/// :echo nvim_get_color_by_name("#cbcbcb")
+/// ```
///
/// @param name Color name or "#rrggbb" string
/// @return 24-bit RGB value, or -1 for invalid argument.
@@ -1420,14 +1422,16 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
/// Empty {rhs} is |<Nop>|. |keycodes| are replaced as usual.
///
/// Example:
-/// <pre>vim
-/// call nvim_set_keymap('n', ' <NL>', '', {'nowait': v:true})
-/// </pre>
+///
+/// ```vim
+/// call nvim_set_keymap('n', ' <NL>', '', {'nowait': v:true})
+/// ```
///
/// is equivalent to:
-/// <pre>vim
-/// nmap <nowait> <Space><NL> <Nop>
-/// </pre>
+///
+/// ```vim
+/// nmap <nowait> <Space><NL> <Nop>
+/// ```
///
/// @param channel_id
/// @param mode Mode short-name (map command prefix: "n", "i", "v", "x", …)
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index ac27554172..63cf3bb701 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -56,16 +56,19 @@
/// this should not be used to specify arbitrary WM screen positions.
///
/// Example (Lua): window-relative float
-/// <pre>lua
-/// vim.api.nvim_open_win(0, false,
-/// {relative='win', row=3, col=3, width=12, height=3})
-/// </pre>
+///
+/// ```lua
+/// vim.api.nvim_open_win(0, false,
+/// {relative='win', row=3, col=3, width=12, height=3})
+/// ```
///
/// Example (Lua): buffer-relative float (travels as buffer is scrolled)
-/// <pre>lua
-/// vim.api.nvim_open_win(0, false,
-/// {relative='win', width=12, height=3, bufpos={100,10}})
-/// </pre>
+///
+/// ```lua
+/// vim.api.nvim_open_win(0, false,
+/// {relative='win', width=12, height=3, bufpos={100,10}})
+/// })
+/// ```
///
/// @param buffer Buffer to display, or 0 for current buffer
/// @param enter Enter the window (make it the current window)
@@ -190,7 +193,8 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, E
}
// autocmds in win_enter or win_set_buf below may close the window
if (win_valid(wp) && buffer > 0) {
- win_set_buf(wp, buf, fconfig.noautocmd, err);
+ Boolean noautocmd = !enter || fconfig.noautocmd;
+ win_set_buf(wp, buf, noautocmd, err);
}
if (!win_valid(wp)) {
api_set_error(err, kErrorTypeException, "Window was closed immediately");
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 265bc11661..f4ca31040a 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -268,6 +268,28 @@ static void decor_add(DecorState *state, int start_row, int start_col, int end_r
kv_A(state->active, index) = range;
}
+/// Initialize the draw_col of a newly-added non-inline virtual text item.
+static void decor_init_draw_col(int win_col, bool hidden, DecorRange *item)
+{
+ if (win_col < 0) {
+ item->draw_col = win_col;
+ } else if (item->decor.virt_text_pos == kVTOverlay) {
+ item->draw_col = (item->decor.virt_text_hide && hidden) ? INT_MIN : win_col;
+ } else {
+ item->draw_col = -1;
+ }
+}
+
+void decor_recheck_draw_col(int win_col, bool hidden, DecorState *state)
+{
+ for (size_t i = 0; i < kv_size(state->active); i++) {
+ DecorRange *item = &kv_A(state->active, i);
+ if (item->draw_col == -3) {
+ decor_init_draw_col(win_col, hidden, item);
+ }
+ }
+}
+
int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *state)
{
buf_T *buf = wp->w_buffer;
@@ -348,19 +370,10 @@ next_mark:
if (active && item.decor.spell != kNone) {
spell = item.decor.spell;
}
- if (item.start_row == state->row && decor_virt_pos(&item.decor)
- && item.draw_col != INT_MIN) {
- if (item.start_col <= col) {
- if (item.decor.virt_text_pos == kVTOverlay && item.draw_col == -1) {
- item.draw_col = (item.decor.virt_text_hide && hidden) ? INT_MIN : win_col;
- } else if (item.draw_col == -3) {
- item.draw_col = -1;
- }
- } else if (wp->w_p_wrap
- && (item.decor.virt_text_pos == kVTRightAlign
- || item.decor.virt_text_pos == kVTWinCol)) {
- item.draw_col = -3;
- }
+ if (item.start_row == state->row && item.start_col <= col
+ && decor_virt_pos(&item.decor) && item.draw_col == -1
+ && item.decor.virt_text_pos != kVTInline) {
+ decor_init_draw_col(win_col, hidden, &item);
}
if (keep) {
kv_A(state->active, j++) = item;
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 3d16aa803e..0f191aa870 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -84,7 +84,7 @@ typedef struct {
bool virt_text_owned;
/// Screen column to draw the virtual text.
/// When -1, the virtual text may be drawn after deciding where.
- /// When -3, the virtual text should be drawn on a later screen line.
+ /// When -3, the virtual text should be drawn on the next screen line.
/// When INT_MIN, the virtual text should no longer be drawn.
int draw_col;
uint64_t ns_id;
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 969021ef2c..e1550e0ece 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -136,8 +136,6 @@ typedef struct {
///< or w_skipcol or concealing
int skipped_cells; ///< nr of skipped cells for virtual text
///< to be added to wlv.vcol later
- bool more_virt_inline_chunks; ///< indicates if there is more inline virtual text
- ///< after n_extra
} winlinevars_T;
/// for line_putchar. Contains the state that needs to be remembered from
@@ -868,10 +866,12 @@ static void apply_cursorline_highlight(win_T *wp, winlinevars_T *wlv)
}
}
-/// Checks if there is more inline virtual text that need to be drawn
-/// and sets has_more_virt_inline_chunks to reflect that.
+/// Checks if there is more inline virtual text that need to be drawn.
static bool has_more_inline_virt(winlinevars_T *wlv, ptrdiff_t v)
{
+ if (wlv->virt_inline_i < kv_size(wlv->virt_inline)) {
+ return true;
+ }
DecorState *state = &decor_state;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
@@ -911,7 +911,6 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
break;
}
}
- wlv->more_virt_inline_chunks = has_more_inline_virt(wlv, v);
if (!kv_size(wlv->virt_inline)) {
// no more inline virtual text here
break;
@@ -929,11 +928,6 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
wlv->c_final = NUL;
wlv->extra_attr = vtc.hl_id ? syn_id2attr(vtc.hl_id) : 0;
wlv->n_attr = mb_charlen(vtc.text);
-
- // Checks if there is more inline virtual text chunks that need to be drawn.
- wlv->more_virt_inline_chunks = has_more_inline_virt(wlv, v)
- || wlv->virt_inline_i < kv_size(wlv->virt_inline);
-
// If the text didn't reach until the first window
// column we need to skip cells.
if (wlv->skip_cells > 0) {
@@ -1147,6 +1141,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
bool saved_search_attr_from_match = false;
int win_col_offset = 0; // offset for window columns
+ bool area_active = false; // whether in Visual selection, for virtual text
+ bool decor_need_recheck = false; // call decor_recheck_draw_col() at next char
char buf_fold[FOLD_TEXT_LEN]; // Hold value returned by get_foldtext
@@ -1788,9 +1784,27 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
if (has_decor && wlv.n_extra == 0) {
- bool selected = (area_highlighting
- && ((wlv.vcol >= wlv.fromcol && wlv.vcol < wlv.tocol)
- || (noinvcur && wlv.vcol == wp->w_virtcol)));
+ // Duplicate the Visual area check after this block,
+ // but don't check inside p_extra here.
+ if (wlv.vcol == wlv.fromcol
+ || (wlv.vcol + 1 == wlv.fromcol
+ && (wlv.n_extra == 0 && utf_ptr2cells(ptr) > 1))
+ || (vcol_prev == fromcol_prev
+ && vcol_prev < wlv.vcol
+ && wlv.vcol < wlv.tocol)) {
+ area_active = true;
+ } else if (area_active
+ && (wlv.vcol == wlv.tocol
+ || (noinvcur && wlv.vcol == wp->w_virtcol))) {
+ area_active = false;
+ }
+
+ bool selected = (area_active || (area_highlighting && noinvcur
+ && wlv.vcol == wp->w_virtcol));
+ if (decor_need_recheck) {
+ decor_recheck_draw_col(wlv.off, selected, &decor_state);
+ decor_need_recheck = false;
+ }
extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state);
if (!has_fold && wp->w_buffer->b_virt_text_inline > 0) {
@@ -1824,10 +1838,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
&& vcol_prev < wlv.vcol // not at margin
&& wlv.vcol < wlv.tocol)) {
*area_attr_p = vi_attr; // start highlighting
+ area_active = true;
} else if (*area_attr_p != 0
&& (wlv.vcol == wlv.tocol
|| (noinvcur && wlv.vcol == wp->w_virtcol))) {
*area_attr_p = 0; // stop highlighting
+ area_active = false;
}
if (!has_fold && wlv.n_extra == 0) {
@@ -2890,15 +2906,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
&& wlv.filler_todo <= 0
&& (wp->w_p_rl ? wlv.col == 0 : wlv.col == grid->cols - 1)
&& !has_fold) {
- if (*ptr == NUL && lcs_eol_one == 0 && has_decor) {
+ if (has_decor && *ptr == NUL && lcs_eol_one == 0) {
// Tricky: there might be a virtual text just _after_ the last char
decor_redraw_col(wp, (colnr_T)v, wlv.off, false, &decor_state);
- handle_inline_virtual_text(wp, &wlv, v);
}
if (*ptr != NUL
|| lcs_eol_one > 0
|| (wlv.n_extra > 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL))
- || wlv.more_virt_inline_chunks) {
+ || has_more_inline_virt(&wlv, v)) {
c = wp->w_p_lcs_chars.ext;
wlv.char_attr = win_hl_attr(wp, HLF_AT);
mb_c = c;
@@ -3085,13 +3100,19 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
wlv.char_attr = saved_attr2;
}
- if ((wp->w_p_rl ? (wlv.col < 0) : (wlv.col >= grid->cols)) && has_decor) {
+ if (has_decor && wlv.filler_todo <= 0
+ && (wp->w_p_rl ? (wlv.col < 0) : (wlv.col >= grid->cols))) {
// At the end of screen line: might need to peek for decorations just after
- // this position. Without wrapping, we might need to display win_pos overlays
- // from the entire text line.
- colnr_T nextpos = wp->w_p_wrap ? (colnr_T)(ptr - line) : (colnr_T)strlen(line);
- decor_redraw_col(wp, nextpos, wlv.off, true, &decor_state);
- handle_inline_virtual_text(wp, &wlv, v);
+ // this position.
+ if (!has_fold && wp->w_p_wrap && wlv.n_extra == 0) {
+ decor_redraw_col(wp, (int)(ptr - line), -3, false, &decor_state);
+ // Check position/hiding of virtual text again on next screen line.
+ decor_need_recheck = true;
+ } else if (has_fold || !wp->w_p_wrap) {
+ // Without wrapping, we might need to display right_align and win_col
+ // virt_text for the entire text line.
+ decor_redraw_col(wp, MAXCOL, -1, true, &decor_state);
+ }
}
// At end of screen line and there is more to come: Display the line
@@ -3104,7 +3125,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL
&& wlv.p_extra != at_end_str)
|| (wlv.n_extra != 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL))
- || wlv.more_virt_inline_chunks)) {
+ || has_more_inline_virt(&wlv, v))) {
bool wrap = wp->w_p_wrap // Wrapping enabled.
&& wlv.filler_todo <= 0 // Not drawing diff filler lines.
&& lcs_eol_one != -1 // Haven't printed the lcs_eol character.
@@ -3117,7 +3138,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
if (virt_line_offset >= 0) {
draw_virt_text_item(buf, virt_line_offset, kv_A(virt_lines, virt_line_index).line,
kHlModeReplace, grid->cols, 0);
- } else {
+ } else if (wlv.filler_todo <= 0) {
draw_virt_text(wp, buf, win_col_offset, &draw_col, grid->cols, wlv.row);
}
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 06eb81be92..216f8a67db 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -4429,9 +4429,8 @@ static bool ins_tab(void)
}
}
if (!(State & VREPLACE_FLAG)) {
- extmark_splice_cols(curbuf, (int)fpos.lnum - 1, change_col,
- cursor->col - change_col, fpos.col - change_col,
- kExtmarkUndo);
+ inserted_bytes(fpos.lnum, change_col,
+ cursor->col - change_col, fpos.col - change_col);
}
}
cursor->col -= i;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 9be4cea059..ec90803884 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -947,38 +947,42 @@ int skip_expr(char **pp, evalarg_T *const evalarg)
return res;
}
+/// Convert "tv" to a string.
+///
+/// @param convert when true convert a List into a sequence of lines.
+///
+/// @return an allocated string.
+static char *typval2string(typval_T *tv, bool convert)
+{
+ if (convert && tv->v_type == VAR_LIST) {
+ garray_T ga;
+ ga_init(&ga, (int)sizeof(char), 80);
+ if (tv->vval.v_list != NULL) {
+ tv_list_join(&ga, tv->vval.v_list, "\n");
+ if (tv_list_len(tv->vval.v_list) > 0) {
+ ga_append(&ga, NL);
+ }
+ }
+ ga_append(&ga, NUL);
+ return (char *)ga.ga_data;
+ }
+ return xstrdup(tv_get_string(tv));
+}
+
/// Top level evaluation function, returning a string.
///
-/// @param convert when true convert a List into a sequence of lines and convert
-/// a Float to a String.
+/// @param convert when true convert a List into a sequence of lines.
///
-/// @return pointer to allocated memory, or NULL for failure.
+/// @return pointer to allocated memory, or NULL for failure.
char *eval_to_string(char *arg, bool convert)
{
typval_T tv;
char *retval;
- garray_T ga;
if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL) {
retval = NULL;
} else {
- if (convert && tv.v_type == VAR_LIST) {
- ga_init(&ga, (int)sizeof(char), 80);
- if (tv.vval.v_list != NULL) {
- tv_list_join(&ga, tv.vval.v_list, "\n");
- if (tv_list_len(tv.vval.v_list) > 0) {
- ga_append(&ga, NL);
- }
- }
- ga_append(&ga, NUL);
- retval = (char *)ga.ga_data;
- } else if (convert && tv.v_type == VAR_FLOAT) {
- char numbuf[NUMBUFLEN];
- vim_snprintf(numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
- retval = xstrdup(numbuf);
- } else {
- retval = xstrdup(tv_get_string(&tv));
- }
+ retval = typval2string(&tv, convert);
tv_clear(&tv);
}
clear_evalarg(&EVALARG_EVALUATE, NULL);
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index e6efbe85d8..2137dc07e4 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -2111,7 +2111,11 @@ M.funcs = {
]=],
name = 'execute',
- params = { { 'command', 'any' }, { 'silent', 'boolean' } },
+ params = {
+ { 'command', 'string|string[]' },
+ { 'silent', "''|'silent'|'silent!'" }
+ },
+ returns = 'string',
signature = 'execute({command} [, {silent}])',
},
exepath = {
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index ab528f8865..35a728314c 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -148,9 +148,7 @@ mapblock_T *get_maphash(int index, buf_T *buf)
/// "mpp" is a pointer to the m_next field of the PREVIOUS entry!
static void mapblock_free(mapblock_T **mpp)
{
- mapblock_T *mp;
-
- mp = *mpp;
+ mapblock_T *mp = *mpp;
xfree(mp->m_keys);
if (!mp->m_simplified) {
NLUA_CLEAR_REF(mp->m_luaref);
@@ -212,8 +210,6 @@ static char *map_mode_to_chars(int mode)
/// @param local true for buffer-local map
static void showmap(mapblock_T *mp, bool local)
{
- size_t len = 1;
-
if (message_filtered(mp->m_keys) && message_filtered(mp->m_str)
&& (mp->m_desc == NULL || message_filtered(mp->m_desc))) {
return;
@@ -226,12 +222,10 @@ static void showmap(mapblock_T *mp, bool local)
}
}
- {
- char *const mapchars = map_mode_to_chars(mp->m_mode);
- msg_puts(mapchars);
- len = strlen(mapchars);
- xfree(mapchars);
- }
+ char *const mapchars = map_mode_to_chars(mp->m_mode);
+ msg_puts(mapchars);
+ size_t len = strlen(mapchars);
+ xfree(mapchars);
while (++len <= 3) {
msg_putchar(' ');
@@ -572,33 +566,16 @@ static void map_add(buf_T *buf, mapblock_T **map_table, mapblock_T **abbr_table,
/// @param buf Target Buffer
static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T *buf)
{
- mapblock_T *mp, **mpp;
- const char *p;
- int n;
int retval = 0;
- mapblock_T **abbr_table;
- mapblock_T **map_table;
- int noremap;
- map_table = maphash;
- abbr_table = &first_abbr;
+ // If <buffer> was given, we'll be searching through the buffer's
+ // mappings/abbreviations, not the globals.
+ mapblock_T **map_table = args->buffer ? buf->b_maphash : maphash;
+ mapblock_T **abbr_table = args->buffer ? &buf->b_first_abbr : &first_abbr;
// For ":noremap" don't remap, otherwise do remap.
- if (maptype == MAPTYPE_NOREMAP) {
- noremap = REMAP_NONE;
- } else {
- noremap = REMAP_YES;
- }
-
- if (args->buffer) {
- // If <buffer> was given, we'll be searching through the buffer's
- // mappings/abbreviations, not the globals.
- map_table = buf->b_maphash;
- abbr_table = &buf->b_first_abbr;
- }
- if (args->script) {
- noremap = REMAP_SCRIPT;
- }
+ int noremap = args->script ? REMAP_SCRIPT :
+ maptype == MAPTYPE_NOREMAP ? REMAP_NONE : REMAP_YES;
const bool has_lhs = (args->lhs[0] != NUL);
const bool has_rhs = args->rhs_lua != LUA_NOREF || (args->rhs[0] != NUL) || args->rhs_is_noop;
@@ -648,8 +625,8 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
const int first = vim_iswordp(lhs);
int last = first;
- p = lhs + utfc_ptr2len(lhs);
- n = 1;
+ const char *p = lhs + utfc_ptr2len(lhs);
+ int n = 1;
while (p < lhs + len) {
n++; // nr of (multi-byte) chars
last = vim_iswordp(p); // type of last char
@@ -685,6 +662,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
&& maptype != MAPTYPE_UNMAP) {
// need to loop over all global hash lists
for (int hash = 0; hash < 256 && !got_int; hash++) {
+ mapblock_T *mp;
if (is_abbrev) {
if (hash != 0) { // there is only one abbreviation list
break;
@@ -714,6 +692,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
if (map_table != buf->b_maphash && !has_rhs && maptype != MAPTYPE_UNMAP) {
// need to loop over all global hash lists
for (int hash = 0; hash < 256 && !got_int; hash++) {
+ mapblock_T *mp;
if (is_abbrev) {
if (hash != 0) { // there is only one abbreviation list
break;
@@ -729,7 +708,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
showmap(mp, true);
did_local = true;
} else {
- n = mp->m_keylen;
+ int n = mp->m_keylen;
if (strncmp(mp->m_keys, lhs, (size_t)(n < len ? n : len)) == 0) {
showmap(mp, true);
did_local = true;
@@ -759,8 +738,8 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
hash_end = 256;
}
for (int hash = hash_start; hash < hash_end && !got_int; hash++) {
- mpp = is_abbrev ? abbr_table : &(map_table[hash]);
- for (mp = *mpp; mp != NULL && !got_int; mp = *mpp) {
+ mapblock_T **mpp = is_abbrev ? abbr_table : &(map_table[hash]);
+ for (mapblock_T *mp = *mpp; mp != NULL && !got_int; mp = *mpp) {
if ((mp->m_mode & mode) == 0) {
// skip entries with wrong mode
mpp = &(mp->m_next);
@@ -772,6 +751,8 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
did_it = true;
}
} else { // do we have a match?
+ int n;
+ const char *p;
if (round) { // second round: Try unmap "rhs" string
n = (int)strlen(mp->m_str);
p = mp->m_str;
@@ -994,12 +975,10 @@ free_and_return:
/// Get the mapping mode from the command name.
static int get_map_mode(char **cmdp, bool forceit)
{
- char *p;
- int modec;
int mode;
- p = *cmdp;
- modec = (uint8_t)(*p++);
+ char *p = *cmdp;
+ int modec = (uint8_t)(*p++);
if (modec == 'i') {
mode = MODE_INSERT; // :imap
} else if (modec == 'l') {
@@ -1036,16 +1015,13 @@ static int get_map_mode(char **cmdp, bool forceit)
/// This function used to be called map_clear().
static void do_mapclear(char *cmdp, char *arg, int forceit, int abbr)
{
- int mode;
- int local;
-
- local = (strcmp(arg, "<buffer>") == 0);
+ bool local = strcmp(arg, "<buffer>") == 0;
if (!local && *arg != NUL) {
emsg(_(e_invarg));
return;
}
- mode = get_map_mode(&cmdp, forceit);
+ int mode = get_map_mode(&cmdp, forceit);
map_clear_mode(curbuf, mode, local, abbr);
}
@@ -1057,11 +1033,8 @@ static void do_mapclear(char *cmdp, char *arg, int forceit, int abbr)
/// @param abbr true for abbreviations
void map_clear_mode(buf_T *buf, int mode, bool local, bool abbr)
{
- mapblock_T *mp, **mpp;
- int hash;
- int new_hash;
-
- for (hash = 0; hash < 256; hash++) {
+ for (int hash = 0; hash < 256; hash++) {
+ mapblock_T **mpp;
if (abbr) {
if (hash > 0) { // there is only one abbrlist
break;
@@ -1079,7 +1052,7 @@ void map_clear_mode(buf_T *buf, int mode, bool local, bool abbr)
}
}
while (*mpp != NULL) {
- mp = *mpp;
+ mapblock_T *mp = *mpp;
if (mp->m_mode & mode) {
mp->m_mode &= ~mode;
if (mp->m_mode == 0) { // entry can be deleted
@@ -1087,7 +1060,7 @@ void map_clear_mode(buf_T *buf, int mode, bool local, bool abbr)
continue;
}
// May need to put this entry into another hash list.
- new_hash = MAP_HASH(mp->m_mode, (uint8_t)mp->m_keys[0]);
+ int new_hash = MAP_HASH(mp->m_mode, (uint8_t)mp->m_keys[0]);
if (!abbr && new_hash != hash) {
*mpp = mp->m_next;
if (local) {
@@ -1119,7 +1092,6 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int mode = 0;
- int retval;
char *buf = NULL;
const char *const rhs = replace_termcodes(str, strlen(str), &buf, 0,
@@ -1141,7 +1113,7 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo
MAPMODE(mode, modechars, 'c', MODE_CMDLINE);
#undef MAPMODE
- retval = map_to_exists_mode(rhs, mode, abbr);
+ int retval = map_to_exists_mode(rhs, mode, abbr);
xfree(buf);
return retval;
@@ -1159,13 +1131,12 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo
/// @return true if there is at least one mapping with given parameters.
int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
{
- mapblock_T *mp;
- int hash;
bool exp_buffer = false;
// Do it twice: once for global maps and once for local maps.
while (true) {
- for (hash = 0; hash < 256; hash++) {
+ for (int hash = 0; hash < 256; hash++) {
+ mapblock_T *mp;
if (abbr) {
if (hash > 0) { // There is only one abbr list.
break;
@@ -1486,10 +1457,7 @@ int ExpandMappings(char *pat, regmatch_T *regmatch, int *numMatches, char ***mat
// Return true if there is an abbreviation, false if not.
bool check_abbr(int c, char *ptr, int col, int mincol)
{
- int scol; // starting column of the abbr.
uint8_t tb[MB_MAXBYTES + 4];
- mapblock_T *mp;
- mapblock_T *mp2;
int clen = 0; // length in characters
if (typebuf.tb_no_abbr_cnt) { // abbrev. are not recursive
@@ -1509,6 +1477,8 @@ bool check_abbr(int c, char *ptr, int col, int mincol)
return false;
}
+ int scol; // starting column of the abbr.
+
{
bool is_id = true;
bool vim_abbr;
@@ -1539,8 +1509,8 @@ bool check_abbr(int c, char *ptr, int col, int mincol)
if (scol < col) { // there is a word in front of the cursor
ptr += scol;
int len = col - scol;
- mp = curbuf->b_first_abbr;
- mp2 = first_abbr;
+ mapblock_T *mp = curbuf->b_first_abbr;
+ mapblock_T *mp2 = first_abbr;
if (mp == NULL) {
mp = mp2;
mp2 = NULL;
@@ -1715,18 +1685,13 @@ char *eval_map_expr(mapblock_T *mp, int c)
/// @param buf buffer for local mappings or NULL
int makemap(FILE *fd, buf_T *buf)
{
- mapblock_T *mp;
- char c1, c2, c3;
- char *p;
- char *cmd;
- int abbr;
- int hash;
bool did_cpo = false;
// Do the loop twice: Once for mappings, once for abbreviations.
// Then loop over all map hash lists.
- for (abbr = 0; abbr < 2; abbr++) {
- for (hash = 0; hash < 256; hash++) {
+ for (int abbr = 0; abbr < 2; abbr++) {
+ for (int hash = 0; hash < 256; hash++) {
+ mapblock_T *mp;
if (abbr) {
if (hash > 0) { // there is only one abbr list
break;
@@ -1755,6 +1720,7 @@ int makemap(FILE *fd, buf_T *buf)
if (mp->m_luaref != LUA_NOREF) {
continue;
}
+ char *p;
for (p = mp->m_str; *p != NUL; p++) {
if ((uint8_t)p[0] == K_SPECIAL && (uint8_t)p[1] == KS_EXTRA
&& p[2] == KE_SNR) {
@@ -1768,14 +1734,10 @@ int makemap(FILE *fd, buf_T *buf)
// It's possible to create a mapping and then ":unmap" certain
// modes. We recreate this here by mapping the individual
// modes, which requires up to three of them.
- c1 = NUL;
- c2 = NUL;
- c3 = NUL;
- if (abbr) {
- cmd = "abbr";
- } else {
- cmd = "map";
- }
+ char c1 = NUL;
+ char c2 = NUL;
+ char c3 = NUL;
+ char *cmd = abbr ? "abbr" : "map";
switch (mp->m_mode) {
case MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING:
break;
@@ -1929,7 +1891,6 @@ int makemap(FILE *fd, buf_T *buf)
int put_escstr(FILE *fd, char *strstart, int what)
{
uint8_t *str = (uint8_t *)strstart;
- int c;
// :map xx <Nop>
if (*str == NUL && what == 1) {
@@ -1953,7 +1914,7 @@ int put_escstr(FILE *fd, char *strstart, int what)
continue;
}
- c = *str;
+ int c = *str;
// Special key codes have to be translated to be able to make sense
// when they are read back.
if (c == K_SPECIAL && what != 2) {
@@ -2030,14 +1991,13 @@ int put_escstr(FILE *fd, char *strstart, int what)
char *check_map(char *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr,
int *local_ptr, int *rhs_lua)
{
- int len, minlen;
- mapblock_T *mp;
*rhs_lua = LUA_NOREF;
- len = (int)strlen(keys);
+ int len = (int)strlen(keys);
for (int local = 1; local >= 0; local--) {
// loop over all hash lists
for (int hash = 0; hash < 256; hash++) {
+ mapblock_T *mp;
if (abbr) {
if (hash > 0) { // there is only one list.
break;
@@ -2062,7 +2022,7 @@ char *check_map(char *keys, int mode, int exact, int ign_mod, int abbr, mapblock
s += 3;
keylen -= 3;
}
- minlen = keylen < len ? keylen : len;
+ int minlen = keylen < len ? keylen : len;
if (strncmp(s, keys, (size_t)minlen) == 0) {
if (mp_ptr != NULL) {
*mp_ptr = mp;
@@ -2097,11 +2057,7 @@ void f_hasmapto(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
}
}
- if (map_to_exists(name, mode, abbr)) {
- rettv->vval.v_number = true;
- } else {
- rettv->vval.v_number = false;
- }
+ rettv->vval.v_number = map_to_exists(name, mode, abbr);
}
/// Fill a Dictionary with all applicable maparg() like dictionaries
@@ -2439,14 +2395,11 @@ void langmap_init(void)
/// changed at any time!
const char *did_set_langmap(optset_T *args)
{
- char *p;
- char *p2;
- int from, to;
-
- ga_clear(&langmap_mapga); // clear the previous map first
- langmap_init(); // back to one-to-one map
+ ga_clear(&langmap_mapga); // clear the previous map first
+ langmap_init(); // back to one-to-one map
- for (p = p_langmap; p[0] != NUL;) {
+ for (char *p = p_langmap; p[0] != NUL;) {
+ char *p2;
for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';';
MB_PTR_ADV(p2)) {
if (p2[0] == '\\' && p2[1] != NUL) {
@@ -2466,8 +2419,8 @@ const char *did_set_langmap(optset_T *args)
if (p[0] == '\\' && p[1] != NUL) {
p++;
}
- from = utf_ptr2char(p);
- to = NUL;
+ int from = utf_ptr2char(p);
+ int to = NUL;
if (p2 == NULL) {
MB_PTR_ADV(p);
if (p[0] != ',') {
@@ -2524,9 +2477,8 @@ const char *did_set_langmap(optset_T *args)
static void do_exmap(exarg_T *eap, int isabbrev)
{
- int mode;
char *cmdp = eap->cmd;
- mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
+ int mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
switch (do_map((*cmdp == 'n') ? MAPTYPE_NOREMAP
: (*cmdp == 'u') ? MAPTYPE_UNMAP : MAPTYPE_MAP,
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index d8b8dbba29..627efa9e96 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -1178,6 +1178,9 @@ void marktree_move(MarkTree *b, MarkTreeIter *itr, int row, int col)
}
if (internal) {
+ if (key.pos.row == newpos.row && key.pos.col == newpos.col) {
+ return;
+ }
key.pos = newpos;
bool match;
// tricky: could minimize movement in either direction better
@@ -1185,14 +1188,14 @@ void marktree_move(MarkTree *b, MarkTreeIter *itr, int row, int col)
if (!match) {
new_i++;
}
- if (new_i == itr->i || key_cmp(key, x->key[new_i]) == 0) {
+ if (new_i == itr->i) {
x->key[itr->i].pos = newpos;
} else if (new_i < itr->i) {
memmove(&x->key[new_i + 1], &x->key[new_i], sizeof(MTKey) * (size_t)(itr->i - new_i));
x->key[new_i] = key;
} else if (new_i > itr->i) {
- memmove(&x->key[itr->i], &x->key[itr->i + 1], sizeof(MTKey) * (size_t)(new_i - itr->i));
- x->key[new_i] = key;
+ memmove(&x->key[itr->i], &x->key[itr->i + 1], sizeof(MTKey) * (size_t)(new_i - itr->i - 1));
+ x->key[new_i - 1] = key;
}
return;
}
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index f0666101b8..3221e5b6e9 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -566,7 +566,7 @@ return {
backups if you don't care about losing the file.
Note that environment variables are not expanded. If you want to use
- $HOME you must expand it explicitly, e.g.: >
+ $HOME you must expand it explicitly, e.g.: >vim
:let &backupskip = escape(expand('$HOME'), '\') .. '/tmp/*'
< Note that the default also makes sure that "crontab -e" works (when a
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 72e21a9130..38e045a08b 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1280,7 +1280,7 @@ static TriState decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_ln
decor_redraw_line(wp, lnum - 1, &decor_state);
*decor_lnum = lnum;
}
- decor_redraw_col(wp, col, col, false, &decor_state);
+ decor_redraw_col(wp, col, 0, false, &decor_state);
return decor_state.spell;
}