diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/autocmd.c | 73 | ||||
-rw-r--r-- | src/nvim/api/buffer.c | 14 | ||||
-rw-r--r-- | src/nvim/api/command.c | 11 | ||||
-rw-r--r-- | src/nvim/api/extmark.c | 38 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 32 | ||||
-rw-r--r-- | src/nvim/api/win_config.c | 22 | ||||
-rw-r--r-- | src/nvim/decoration.c | 39 | ||||
-rw-r--r-- | src/nvim/decoration.h | 2 | ||||
-rw-r--r-- | src/nvim/drawline.c | 69 | ||||
-rw-r--r-- | src/nvim/edit.c | 5 | ||||
-rw-r--r-- | src/nvim/eval.c | 46 | ||||
-rw-r--r-- | src/nvim/eval.lua | 6 | ||||
-rw-r--r-- | src/nvim/mapping.c | 158 | ||||
-rw-r--r-- | src/nvim/marktree.c | 9 | ||||
-rw-r--r-- | src/nvim/options.lua | 2 | ||||
-rw-r--r-- | src/nvim/spell.c | 2 |
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; } |