diff options
Diffstat (limited to 'src')
117 files changed, 2928 insertions, 2524 deletions
diff --git a/src/clint.py b/src/clint.py index 9b4128a0c9..4a5e435bbd 100755 --- a/src/clint.py +++ b/src/clint.py @@ -68,7 +68,7 @@ Syntax: clint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] <file> [file] ... The style guidelines this tries to follow are those in - http://neovim.io/development-wiki/style-guide/style-guide.xml + http://neovim.io/develop/style-guide.xml Note: This is Google's cpplint.py modified for use with the Neovim project, which follows the Google C++ coding convention except with the following diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index b371c08d2a..878ffdf06f 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -315,7 +315,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, } rv.size = (size_t)(end - start); - rv.items = xcalloc(sizeof(Object), rv.size); + rv.items = xcalloc(rv.size, sizeof(Object)); if (!buf_collect_lines(buf, rv.size, start, (channel_id != VIML_INTERNAL_CALL), &rv, err)) { @@ -1433,8 +1433,14 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, /// - hl_group : name of the highlight group used to highlight /// this mark. /// - virt_text : virtual text to link to this mark. -/// - virt_text_pos : positioning of virtual text. Possible -/// values: +/// A list of [text, highlight] tuples, each representing a +/// text chunk with specified highlight. `highlight` element +/// can either be a a single highlight group, or an array of +/// multiple highlight groups that will be stacked +/// (highest priority last). A highlight group can be supplied +/// either as a string or as an integer, the latter which +/// can be obtained using |nvim_get_hl_id_by_name|. +/// - virt_text_pos : position of virtual text. Possible values: /// - "eol": right after eol character (default) /// - "overlay": display over the specified column, without /// shifting the underlying text. @@ -1480,7 +1486,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, { buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { - api_set_error(err, kErrorTypeValidation, "Invalid buffer id"); return 0; } @@ -1560,7 +1565,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, "virt_text is not an Array"); goto error; } - decor.virt_text = parse_virt_text(v->data.array, err); + decor.virt_text = parse_virt_text(v->data.array, err, + &decor.virt_text_width); if (ERROR_SET(err)) { goto error; } @@ -1892,80 +1898,6 @@ void nvim_buf_clear_namespace(Buffer buffer, (int)line_end-1, MAXCOL); } -/// Set the virtual text (annotation) for a buffer line. -/// -/// By default (and currently the only option) the text will be placed after -/// the buffer text. Virtual text will never cause reflow, rather virtual -/// text will be truncated at the end of the screen line. The virtual text will -/// begin one cell (|lcs-eol| or space) after the ordinary text. -/// -/// Namespaces are used to support batch deletion/updating of virtual text. -/// To create a namespace, use |nvim_create_namespace()|. Virtual text is -/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for -/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both -/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If -/// the virtual text never will be cleared by an API call, pass `ns_id = -1`. -/// -/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the -/// virtual text, the allocated id is then returned. -/// -/// @param buffer Buffer handle, or 0 for current buffer -/// @param ns_id Namespace to use or 0 to create a namespace, -/// or -1 for a ungrouped annotation -/// @param line Line to annotate with virtual text (zero-indexed) -/// @param chunks A list of [text, hl_group] arrays, each representing a -/// text chunk with specified highlight. `hl_group` element -/// can be omitted for no highlight. -/// @param opts Optional parameters. Currently not used. -/// @param[out] err Error details, if any -/// @return The ns_id that was used -Integer nvim_buf_set_virtual_text(Buffer buffer, - Integer src_id, - Integer line, - Array chunks, - Dictionary opts, - Error *err) - FUNC_API_SINCE(5) -{ - buf_T *buf = find_buffer_by_handle(buffer, err); - if (!buf) { - return 0; - } - - if (line < 0 || line >= MAXLNUM) { - api_set_error(err, kErrorTypeValidation, "Line number outside range"); - return 0; - } - - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); - return 0; - } - - uint64_t ns_id = src2ns(&src_id); - - VirtText virt_text = parse_virt_text(chunks, err); - if (ERROR_SET(err)) { - return 0; - } - - - VirtText *existing = decor_find_virttext(buf, (int)line, ns_id); - - if (existing) { - clear_virttext(existing); - *existing = virt_text; - return src_id; - } - - Decoration *decor = xcalloc(1, sizeof(*decor)); - decor->virt_text = virt_text; - - extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true, - false, kExtmarkNoUndo); - return src_id; -} - /// call a function with buffer as temporary current buffer /// /// This temporarily switches current buffer to "buffer". diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 3989386bb9..554966e266 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -12,6 +12,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/lua/executor.h" +#include "nvim/extmark.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/deprecated.c.generated.h" @@ -80,6 +81,87 @@ void nvim_buf_clear_highlight(Buffer buffer, } +/// Set the virtual text (annotation) for a buffer line. +/// +/// @deprecated use nvim_buf_set_extmark to use full virtual text +/// functionality. +/// +/// The text will be placed after the buffer text. Virtual text will never +/// cause reflow, rather virtual text will be truncated at the end of the screen +/// line. The virtual text will begin one cell (|lcs-eol| or space) after the +/// ordinary text. +/// +/// Namespaces are used to support batch deletion/updating of virtual text. +/// To create a namespace, use |nvim_create_namespace()|. Virtual text is +/// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for +/// both virtual text and highlights added by |nvim_buf_add_highlight()|, both +/// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If +/// the virtual text never will be cleared by an API call, pass `ns_id = -1`. +/// +/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the +/// virtual text, the allocated id is then returned. +/// +/// @param buffer Buffer handle, or 0 for current buffer +/// @param ns_id Namespace to use or 0 to create a namespace, +/// or -1 for a ungrouped annotation +/// @param line Line to annotate with virtual text (zero-indexed) +/// @param chunks A list of [text, hl_group] arrays, each representing a +/// text chunk with specified highlight. `hl_group` element +/// can be omitted for no highlight. +/// @param opts Optional parameters. Currently not used. +/// @param[out] err Error details, if any +/// @return The ns_id that was used +Integer nvim_buf_set_virtual_text(Buffer buffer, + Integer src_id, + Integer line, + Array chunks, + Dictionary opts, + Error *err) + FUNC_API_SINCE(5) + FUNC_API_DEPRECATED_SINCE(8) +{ + buf_T *buf = find_buffer_by_handle(buffer, err); + if (!buf) { + return 0; + } + + if (line < 0 || line >= MAXLNUM) { + api_set_error(err, kErrorTypeValidation, "Line number outside range"); + return 0; + } + + if (opts.size > 0) { + api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); + return 0; + } + + uint64_t ns_id = src2ns(&src_id); + int width; + + VirtText virt_text = parse_virt_text(chunks, err, &width); + if (ERROR_SET(err)) { + return 0; + } + + + Decoration *existing = decor_find_virttext(buf, (int)line, ns_id); + + if (existing) { + clear_virttext(&existing->virt_text); + existing->virt_text = virt_text; + existing->virt_text_width = width; + return src_id; + } + + Decoration *decor = xcalloc(1, sizeof(*decor)); + decor->virt_text = virt_text; + decor->virt_text_width = width; + + extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true, + false, kExtmarkNoUndo); + return src_id; +} + /// Inserts a sequence of lines to a buffer at a certain index /// /// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines) diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index c7d261ba18..3ec6151090 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -1592,9 +1592,10 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int } } -VirtText parse_virt_text(Array chunks, Error *err) +VirtText parse_virt_text(Array chunks, Error *err, int *width) { VirtText virt_text = KV_INITIAL_VALUE; + int w = 0; for (size_t i = 0; i < chunks.size; i++) { if (chunks.items[i].type != kObjectTypeArray) { api_set_error(err, kErrorTypeValidation, "Chunk is not an array"); @@ -1602,26 +1603,44 @@ VirtText parse_virt_text(Array chunks, Error *err) } Array chunk = chunks.items[i].data.array; if (chunk.size == 0 || chunk.size > 2 - || chunk.items[0].type != kObjectTypeString - || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) { + || chunk.items[0].type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, "Chunk is not an array with one or two strings"); goto free_exit; } String str = chunk.items[0].data.string; - char *text = transstr(str.size > 0 ? str.data : ""); // allocates int hl_id = 0; if (chunk.size == 2) { - String hl = chunk.items[1].data.string; - if (hl.size > 0) { - hl_id = syn_check_group((char_u *)hl.data, (int)hl.size); + Object hl = chunk.items[1]; + if (hl.type == kObjectTypeArray) { + Array arr = hl.data.array; + for (size_t j = 0; j < arr.size; j++) { + hl_id = object_to_hl_id(arr.items[j], "virt_text highlight", err); + if (ERROR_SET(err)) { + goto free_exit; + } + if (j < arr.size-1) { + kv_push(virt_text, ((VirtTextChunk){ .text = NULL, + .hl_id = hl_id })); + } + } + } else { + hl_id = object_to_hl_id(hl, "virt_text highlight", err); + if (ERROR_SET(err)) { + goto free_exit; + } } } + + char *text = transstr(str.size > 0 ? str.data : ""); // allocates + w += (int)mb_string2cells((char_u *)text); + kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id })); } + *width = w; return virt_text; free_exit: @@ -1656,7 +1675,7 @@ int object_to_hl_id(Object obj, const char *what, Error *err) String str = obj.data.string; return str.size ? syn_check_group((char_u *)str.data, (int)str.size) : 0; } else if (obj.type == kObjectTypeInteger) { - return (int)obj.data.integer; + return MAX((int)obj.data.integer, 0); } else { api_set_error(err, kErrorTypeValidation, "%s is not a valid highlight", what); @@ -1687,6 +1706,7 @@ HlMessage parse_hl_msg(Array chunks, Error *err) if (chunk.size == 2) { String hl = chunk.items[1].data.string; if (hl.size > 0) { + // TODO(bfredl): use object_to_hl_id and allow integer int hl_id = syn_check_group((char_u *)hl.data, (int)hl.size); attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; } @@ -1790,7 +1810,7 @@ static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) } for (size_t i = 0; i < size; i++) { Object iytem = arr.items[i]; - String string = NULL_STRING; + String string; int hl_id = 0; if (iytem.type == kObjectTypeArray) { Array iarr = iytem.data.array; diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 51f1af4eb5..63e6ad883a 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -158,7 +158,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, } if (ui->ui_ext[kUIMessages]) { - // This uses attribute indicies, so ext_linegrid is needed. + // This uses attribute indices, so ext_linegrid is needed. ui->ui_ext[kUILinegrid] = true; // Cmdline uses the messages area, so it should be externalized too. ui->ui_ext[kUICmdline] = true; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 349cc0e7da..400dbb126c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -217,7 +217,7 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) /// /// @param ns_id number of namespace for this highlight /// @param name highlight group name, like ErrorMsg -/// @param val highlight definiton map, like |nvim_get_hl_by_name|. +/// @param val highlight definition map, like |nvim_get_hl_by_name|. /// in addition the following keys are also recognized: /// `default`: don't override existing definition, /// like `hi default` @@ -384,7 +384,7 @@ Integer nvim_input(String keys) /// by calling it multiple times in a loop: the intermediate mouse /// positions will be ignored. It should be used to implement real-time /// mouse input in a GUI. The deprecated pseudokey form -/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitiation. +/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitation. /// /// @param button Mouse button: one of "left", "right", "middle", "wheel". /// @param action For ordinary buttons, one of "press", "drag", "release". @@ -558,7 +558,7 @@ Object nvim_exec_lua(String code, Array args, Error *err) /// Notify the user with a message /// /// Relays the call to vim.notify . By default forwards your message in the -/// echo area but can be overriden to trigger desktop notifications. +/// echo area but can be overridden to trigger desktop notifications. /// /// @param msg Message to display to the user /// @param log_level The log level @@ -1260,7 +1260,7 @@ fail: /// /// By default (and currently the only option) the terminal will not be /// connected to an external process. Instead, input send on the channel -/// will be echoed directly by the terminal. This is useful to disply +/// will be echoed directly by the terminal. This is useful to display /// ANSI terminal sequences returned as part of a rpc message, or similar. /// /// Note: to directly initiate the terminal using the right size, display the @@ -1290,7 +1290,7 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err) TerminalOptions topts; Channel *chan = channel_alloc(kChannelStreamInternal); topts.data = chan; - // NB: overriden in terminal_check_size if a window is already + // NB: overridden in terminal_check_size if a window is already // displaying the buffer topts.width = (uint16_t)MAX(curwin->w_width_inner - win_col_off(curwin), 0); topts.height = (uint16_t)curwin->w_height_inner; @@ -1557,7 +1557,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) /// Creates a new namespace, or gets an existing one. /// /// Namespaces are used for buffer highlights and virtual text, see -/// |nvim_buf_add_highlight()| and |nvim_buf_set_virtual_text()|. +/// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. /// /// Namespaces can be named or anonymous. If `name` matches an existing /// namespace, the associated id is returned. If `name` is an empty string @@ -1696,7 +1696,7 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, FUNC_API_SINCE(6) FUNC_API_CHECK_TEXTLOCK { - yankreg_T *reg = xcalloc(sizeof(yankreg_T), 1); + yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); if (!prepare_yankreg_from_object(reg, type, lines.size)) { api_set_error(err, kErrorTypeValidation, "Invalid type: '%s'", type.data); goto cleanup; @@ -2237,7 +2237,7 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack; /// - "arg": String, error message argument. /// - "len": Amount of bytes successfully parsed. With flags equal to "" /// that should be equal to the length of expr string. -/// (“Sucessfully parsed” here means “participated in AST +/// (“Successfully parsed” here means “participated in AST /// creation”, not “till the first error”.) /// - "ast": AST, either nil or a dictionary with these keys: /// - "type": node type, one of the value names from ExprASTNodeType @@ -2301,7 +2301,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, } } } - ParserLine plines[] = { + ParserLine parser_lines[] = { { .data = expr.data, .size = expr.size, @@ -2309,7 +2309,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, }, { NULL, 0, false }, }; - ParserLine *plines_p = plines; + ParserLine *plines_p = parser_lines; ParserHighlight colors; kvi_init(colors); ParserHighlight *const colors_p = (highlight ? &colors : NULL); @@ -2335,7 +2335,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, ret.items[ret.size++] = (KeyValuePair) { .key = STATIC_CSTR_TO_STRING("len"), .value = INTEGER_OBJ((Integer)(pstate.pos.line == 1 - ? plines[0].size + ? parser_lines[0].size : pstate.pos.col)), }; if (east.err.msg != NULL) { @@ -2925,7 +2925,7 @@ void nvim__screenshot(String path) /// Note: this function should not be called often. Rather, the callbacks /// themselves can be used to throttle unneeded callbacks. the `on_start` /// callback can return `false` to disable the provider until the next redraw. -/// Similarily, return `false` in `on_win` will skip the `on_lines` calls +/// Similarly, return `false` in `on_win` will skip the `on_lines` calls /// for that window (but any extmarks set in `on_win` will still be used). /// A plugin managing multiple sources of decoration should ideally only set /// one provider, and merge the sources internally. You can use multiple `ns_id` diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 094328b5b0..069dfae233 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -394,7 +394,7 @@ void nvim_win_set_config(Window window, Dictionary config, Error *err) return; } bool new_float = !win->w_floating; - // reuse old values, if not overriden + // reuse old values, if not overridden FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; if (!parse_float_config(config, &fconfig, !new_float, false, err)) { diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c index 9fba38a49f..7ea2e0cf9b 100644 --- a/src/nvim/arabic.c +++ b/src/nvim/arabic.c @@ -793,7 +793,7 @@ bool arabic_maycombine(int two) return false; } -// A_firstc_laa returns first character of LAA combination if it ex.ists +// A_firstc_laa returns first character of LAA combination if it exists // in: "c" base character // in: "c1" first composing character static int A_firstc_laa(int c, int c1) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f1f32076bf..587ef74b35 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -55,7 +55,6 @@ #include "nvim/mark.h" #include "nvim/extmark.h" #include "nvim/mbyte.h" -#include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" @@ -139,7 +138,7 @@ read_buffer( if (read_stdin) { // Set or reset 'modified' before executing autocommands, so that // it can be changed there. - if (!readonlymode && !BUFEMPTY()) { + if (!readonlymode && !buf_is_empty(curbuf)) { changed(); } else if (retval != FAIL) { unchanged(curbuf, false, true); @@ -541,12 +540,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) del_buf = true; } - /* - * Free all things allocated for this buffer. - * Also calls the "BufDelete" autocommands when del_buf is TRUE. - */ - /* Remember if we are closing the current buffer. Restore the number of - * windows, so that autocommands in buf_freeall() don't get confused. */ + // Free all things allocated for this buffer. + // Also calls the "BufDelete" autocommands when del_buf is true. + // Remember if we are closing the current buffer. Restore the number of + // windows, so that autocommands in buf_freeall() don't get confused. bool is_curbuf = (buf == curbuf); // When closing the current buffer stop Visual mode before freeing @@ -901,7 +898,10 @@ void handle_swap_exists(bufref_T *old_curbuf) if (old_curbuf == NULL || !bufref_valid(old_curbuf) || old_curbuf->br_buf == curbuf) { + // Block autocommands here because curwin->w_buffer is NULL. + block_autocmds(); buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); + unblock_autocmds(); } else { buf = old_curbuf->br_buf; } @@ -1489,7 +1489,7 @@ void set_curbuf(buf_T *buf, int action) set_bufref(&prevbufref, prevbuf); set_bufref(&newbufref, buf); - // Autocommands may delete the curren buffer and/or the buffer we wan to go + // Autocommands may delete the curren buffer and/or the buffer we want to go // to. In those cases don't close the buffer. if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf) || (bufref_valid(&prevbufref) && bufref_valid(&newbufref) @@ -1670,7 +1670,7 @@ static int top_file_num = 1; ///< highest file number /// Initialize b:changedtick and changedtick_val attribute /// -/// @param[out] buf Buffer to intialize for. +/// @param[out] buf Buffer to initialize for. static inline void buf_init_changedtick(buf_T *const buf) FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL { @@ -1783,7 +1783,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, buf = xcalloc(1, sizeof(buf_T)); // init b: variables buf->b_vars = tv_dict_alloc(); - buf->b_signcols_max = -1; + buf->b_signcols_valid = false; init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE); buf_init_changedtick(buf); } @@ -1918,7 +1918,7 @@ bool curbuf_reusable(void) return (curbuf != NULL && curbuf->b_ffname == NULL && curbuf->b_nwindows <= 1 - && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY()) + && (curbuf->b_ml.ml_mfp == NULL || buf_is_empty(curbuf)) && !bt_quickfix(curbuf) && !curbufIsChanged()); } @@ -2058,7 +2058,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) // If 'switchbuf' contains "split", "vsplit" or "newtab" and the // current buffer isn't empty: open new tab or window if (wp == NULL && (swb_flags & (SWB_VSPLIT | SWB_SPLIT | SWB_NEWTAB)) - && !BUFEMPTY()) { + && !buf_is_empty(curbuf)) { if (swb_flags & SWB_NEWTAB) { tabpage_new(); } else if (win_split(0, (swb_flags & SWB_VSPLIT) ? WSP_VERT : 0) @@ -3587,7 +3587,7 @@ int build_stl_str_hl( // Proceed character by character through the statusline format string - // fmt_p is the current positon in the input buffer + // fmt_p is the current position in the input buffer for (char_u *fmt_p = usefmt; *fmt_p; ) { if (curitem == (int)stl_items_len) { size_t new_len = stl_items_len * 3 / 2; @@ -4735,7 +4735,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) // When resolving a link both "*sfname" and "*ffname" will point to the same // allocated memory. // The "*ffname" and "*sfname" pointer values on call will not be freed. -// Note that the resulting "*ffname" pointer should be considered not allocaed. +// Note that the resulting "*ffname" pointer should be considered not allocated. void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) { if (*ffname == NULL) { // no file name given, nothing to do @@ -4948,7 +4948,7 @@ do_arg_all( win_enter(lastwin, false); // ":tab drop file" should re-use an empty window to avoid "--remote-tab" // leaving an empty tab page when executed locally. - if (keep_tabs && BUFEMPTY() && curbuf->b_nwindows == 1 + if (keep_tabs && buf_is_empty(curbuf) && curbuf->b_nwindows == 1 && curbuf->b_ffname == NULL && !curbuf->b_changed) { use_firstwin = true; tab_drop_empty_window = true; @@ -5044,8 +5044,8 @@ do_arg_all( xfree(opened); } -// Return TRUE if "buf" is a prompt buffer. -int bt_prompt(buf_T *buf) +/// @return true if "buf" is a prompt buffer. +bool bt_prompt(buf_T *buf) { return buf != NULL && buf->b_p_bt[0] == 'p'; } @@ -5544,16 +5544,16 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) int buf_signcols(buf_T *buf) { - if (buf->b_signcols_max == -1) { + if (!buf->b_signcols_valid) { sign_entry_T *sign; // a sign in the sign list - buf->b_signcols_max = 0; + int signcols = 0; int linesum = 0; linenr_T curline = 0; FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->se_lnum > curline) { - if (linesum > buf->b_signcols_max) { - buf->b_signcols_max = linesum; + if (linesum > signcols) { + signcols = linesum; } curline = sign->se_lnum; linesum = 0; @@ -5562,15 +5562,17 @@ int buf_signcols(buf_T *buf) linesum++; } } - if (linesum > buf->b_signcols_max) { - buf->b_signcols_max = linesum; + if (linesum > signcols) { + signcols = linesum; } // Check if we need to redraw - if (buf->b_signcols_max != buf->b_signcols) { - buf->b_signcols = buf->b_signcols_max; + if (signcols != buf->b_signcols) { + buf->b_signcols = signcols; redraw_buf_later(buf, NOT_VALID); } + + buf->b_signcols_valid = true; } return buf->b_signcols; @@ -5691,3 +5693,4 @@ void buf_open_scratch(handle_T bufnr, char *bufname) set_option_value("swf", 0L, NULL, OPT_LOCAL); RESET_BINDING(curwin); } + diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index ac7ead5f92..02a2ac36f7 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -9,6 +9,7 @@ #include "nvim/func_attr.h" #include "nvim/eval.h" #include "nvim/macros.h" +#include "nvim/memline.h" // Values for buflist_getfile() enum getf_values { @@ -128,4 +129,10 @@ static inline void buf_inc_changedtick(buf_T *const buf) buf_set_changedtick(buf, buf_get_changedtick(buf) + 1); } +static inline bool buf_is_empty(buf_T *buf) +{ + return buf->b_ml.ml_line_count == 1 + && *ml_get_buf(buf, (linenr_T)1, false) == '\0'; +} + #endif // NVIM_BUFFER_H diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index e3e538bd12..b03d69a04c 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -226,6 +226,8 @@ typedef struct { # define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn' int wo_cul; # define w_p_cul w_onebuf_opt.wo_cul // 'cursorline' + char_u *wo_culopt; +# define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt' char_u *wo_cc; # define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn' char_u *wo_stl; @@ -525,6 +527,8 @@ struct file_buffer { int b_flags; // various BF_ flags int b_locked; // Buffer is being closed or referenced, don't // let autocommands wipe it out. + int b_ro_locked; // Non-zero when the buffer can't be changed. + // Used for FileChangedRO // // b_ffname has the full path of the file (NULL for no name). @@ -849,8 +853,8 @@ struct file_buffer { // may use a different synblock_T. sign_entry_T *b_signlist; // list of placed signs - int b_signcols_max; // cached maximum number of sign columns int b_signcols; // last calculated number of sign columns + bool b_signcols_valid; // calculated sign columns is valid Terminal *terminal; // Terminal instance associated with the buffer @@ -1294,7 +1298,7 @@ struct window_S { /* * w_cline_height is the number of physical lines taken by the buffer line - * that the cursor is on. We use this to avoid extra calls to plines(). + * that the cursor is on. We use this to avoid extra calls to plines_win(). */ int w_cline_height; // current size of cursor line bool w_cline_folded; // cursor line is folded @@ -1384,12 +1388,14 @@ struct window_S { uint32_t w_p_fde_flags; // flags for 'foldexpr' uint32_t w_p_fdt_flags; // flags for 'foldtext' int *w_p_cc_cols; // array of columns to highlight or NULL + char_u w_p_culopt_flags; // flags for cursorline highlighting long w_p_siso; // 'sidescrolloff' local value long w_p_so; // 'scrolloff' local value int w_briopt_min; // minimum width for breakindent int w_briopt_shift; // additional shift for breakindent bool w_briopt_sbr; // sbr in 'briopt' + int w_briopt_list; // additional indent for lists // transform a pointer to a "onebuf" option into a "allbuf" option #define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T)) diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index 5c573530d1..1d131cc4b1 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -50,7 +50,7 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id, if (send_buffer) { Array args = ARRAY_DICT_INIT; args.size = 6; - args.items = xcalloc(sizeof(Object), args.size); + args.items = xcalloc(args.size, sizeof(Object)); // the first argument is always the buffer handle args.items[0] = BUFFER_OBJ(buf->handle); @@ -68,7 +68,7 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id, if (line_count >= 1) { linedata.size = line_count; - linedata.items = xcalloc(sizeof(Object), line_count); + linedata.items = xcalloc(line_count, sizeof(Object)); buf_collect_lines(buf, line_count, 1, true, &linedata, NULL); } @@ -93,7 +93,7 @@ void buf_updates_send_end(buf_T *buf, uint64_t channelid) { Array args = ARRAY_DICT_INIT; args.size = 1; - args.items = xcalloc(sizeof(Object), args.size); + args.items = xcalloc(args.size, sizeof(Object)); args.items[0] = BUFFER_OBJ(buf->handle); rpc_send_event(channelid, "nvim_buf_detach_event", args); } @@ -211,7 +211,7 @@ void buf_updates_send_changes(buf_T *buf, // send through the changes now channel contents now Array args = ARRAY_DICT_INIT; args.size = 6; - args.items = xcalloc(sizeof(Object), args.size); + args.items = xcalloc(args.size, sizeof(Object)); // the first argument is always the buffer handle args.items[0] = BUFFER_OBJ(buf->handle); @@ -230,7 +230,7 @@ void buf_updates_send_changes(buf_T *buf, if (num_added > 0) { STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM"); linedata.size = (size_t)num_added; - linedata.items = xcalloc(sizeof(Object), (size_t)num_added); + linedata.items = xcalloc((size_t)num_added, sizeof(Object)); buf_collect_lines(buf, (size_t)num_added, firstline, true, &linedata, NULL); } @@ -313,7 +313,7 @@ void buf_updates_send_splice( return; } - // notify each of the active callbakcs + // notify each of the active callbacks size_t j = 0; for (size_t i = 0; i < kv_size(buf->update_callbacks); i++) { BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i); @@ -394,7 +394,7 @@ void buf_updates_changedtick_single(buf_T *buf, uint64_t channel_id) { Array args = ARRAY_DICT_INIT; args.size = 2; - args.items = xcalloc(sizeof(Object), args.size); + args.items = xcalloc(args.size, sizeof(Object)); // the first argument is always the buffer handle args.items[0] = BUFFER_OBJ(buf->handle); diff --git a/src/nvim/change.c b/src/nvim/change.c index c0183d4317..41e1e3911b 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -22,6 +22,7 @@ #include "nvim/misc1.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" @@ -40,18 +41,18 @@ /// "col" is the column for the message; non-zero when in insert mode and /// 'showmode' is on. /// Careful: may trigger autocommands that reload the buffer. -void change_warning(int col) +void change_warning(buf_T *buf, int col) { static char *w_readonly = N_("W10: Warning: Changing a readonly file"); - if (curbuf->b_did_warn == false + if (buf->b_did_warn == false && curbufIsChanged() == 0 && !autocmd_busy - && curbuf->b_p_ro) { - curbuf_lock++; - apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, curbuf); - curbuf_lock--; - if (!curbuf->b_p_ro) { + && buf->b_p_ro) { + buf->b_ro_locked++; + apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, false, buf); + buf->b_ro_locked--; + if (!buf->b_p_ro) { return; } // Do what msg() does, but with a column offset if the warning should @@ -70,7 +71,7 @@ void change_warning(int col) ui_flush(); os_delay(1002L, true); // give the user time to think about it } - curbuf->b_did_warn = true; + buf->b_did_warn = true; redraw_cmdline = false; // don't redraw and erase the message if (msg_row < Rows - 1) { showmode(); @@ -91,14 +92,14 @@ void changed(void) // Give a warning about changing a read-only file. This may also // check-out the file, thus change "curbuf"! - change_warning(0); + change_warning(curbuf, 0); // Create a swap file if that is wanted. // Don't do this for "nofile" and "nowrite" buffer types. if (curbuf->b_may_swap && !bt_dontwrite(curbuf) ) { - int save_need_wait_return = need_wait_return; + bool save_need_wait_return = need_wait_return; need_wait_return = false; ml_open_file(curbuf); @@ -290,13 +291,21 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, set_topline(wp, wp->w_topline); } - // Relative numbering may require updating more. Cursor line - // highlighting probably needs to be updated if it's below the - // change. - if (wp->w_p_rnu - || (wp->w_p_cul && lnum <= wp->w_last_cursorline)) { + // Relative numbering may require updating more. + if (wp->w_p_rnu) { redraw_later(wp, SOME_VALID); } + + // Cursor line highlighting probably need to be updated with + // "VALID" if it's below the change. + // If the cursor line is inside the change we need to redraw more. + if (wp->w_p_cul) { + if (xtra == 0) { + redraw_later(wp, VALID); + } else if (lnum <= wp->w_last_cursorline) { + redraw_later(wp, SOME_VALID); + } + } } } @@ -585,9 +594,9 @@ void ins_char_bytes(char_u *buf, size_t charlen) // cells. May result in adding spaces to fill a gap. colnr_T vcol; getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL); - colnr_T new_vcol = vcol + chartabsize(buf, vcol); + colnr_T new_vcol = vcol + win_chartabsize(curwin, buf, vcol); while (oldp[col + oldlen] != NUL && vcol < new_vcol) { - vcol += chartabsize(oldp + col + oldlen, vcol); + vcol += win_chartabsize(curwin, oldp + col + oldlen, vcol); // Don't need to remove a TAB that takes us to the right // position. if (vcol > new_vcol && oldp[col + oldlen] == TAB) { @@ -779,7 +788,7 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine) int movelen = oldlen - col - count + 1; // includes trailing NUL if (movelen <= 1) { // If we just took off the last character of a non-blank line, and - // fixpos is TRUE, we don't want to end up positioned at the NUL, + // fixpos is true, we don't want to end up positioned at the NUL, // unless "restart_edit" is set or 'virtualedit' contains "onemore". if (col > 0 && fixpos && restart_edit == 0 && (ve_flags & VE_ONEMORE) == 0 @@ -1732,7 +1741,7 @@ int open_line( } if (did_append) { changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true); - // bail out and just get the final lenght of the line we just manipulated + // bail out and just get the final length of the line we just manipulated bcount_t extra = (bcount_t)STRLEN(ml_get(curwin->w_cursor.lnum)); extmark_splice(curbuf, (int)curwin->w_cursor.lnum-1, 0, 0, 0, 0, 1, 0, 1+extra, kExtmarkUndo); diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 60af11e94b..a0db1bcdfd 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -289,6 +289,9 @@ static void close_cb(Stream *stream, void *data) /// `on_stdout` is ignored /// @param[in] detach True if the job should not be killed when nvim exits, /// ignored if `pty` is true +/// @param[in] stdin_mode Stdin mode. Either kChannelStdinPipe to open a +/// channel for stdin or kChannelStdinNull to leave +/// stdin disconnected. /// @param[in] cwd Initial working directory for the job. Nvim's working /// directory if `cwd` is NULL /// @param[in] pty_width Width of the pty, ignored if `pty` is false @@ -302,7 +305,7 @@ static void close_cb(Stream *stream, void *data) Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader on_stderr, Callback on_exit, bool pty, bool rpc, bool overlapped, bool detach, - const char *cwd, + ChannelStdinMode stdin_mode, const char *cwd, uint16_t pty_width, uint16_t pty_height, dict_T *env, varnumber_T *status_out) { @@ -345,7 +348,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, proc->overlapped = overlapped; char *cmd = xstrdup(proc->argv[0]); - bool has_out, has_err; + bool has_in, has_out, has_err; if (proc->type == kProcessTypePty) { has_out = true; has_err = false; @@ -353,7 +356,17 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, has_out = rpc || callback_reader_set(chan->on_data); has_err = callback_reader_set(chan->on_stderr); } - int status = process_spawn(proc, true, has_out, has_err); + + switch (stdin_mode) { + case kChannelStdinPipe: + has_in = true; + break; + case kChannelStdinNull: + has_in = false; + break; + } + + int status = process_spawn(proc, has_in, has_out, has_err); if (status) { EMSG3(_(e_jobspawn), os_strerror(status), cmd); xfree(cmd); @@ -369,7 +382,9 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, tv_dict_free(proc->env); } - wstream_init(&proc->in, 0); + if (has_in) { + wstream_init(&proc->in, 0); + } if (has_out) { rstream_init(&proc->out, 0); } diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 9d26852ce5..df858e1602 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -28,6 +28,10 @@ typedef enum { kChannelPartAll } ChannelPart; +typedef enum { + kChannelStdinPipe, + kChannelStdinNull, +} ChannelStdinMode; typedef struct { Stream in; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index e2d844a351..0252ef4e9c 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -25,6 +25,7 @@ #include "nvim/move.h" #include "nvim/option.h" #include "nvim/os_unix.h" +#include "nvim/plines.h" #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/path.h" @@ -733,80 +734,6 @@ int vim_strnsize(char_u *s, int len) return size; } -/// Return the number of characters 'c' will take on the screen, taking -/// into account the size of a tab. -/// Use a define to make it fast, this is used very often!!! -/// Also see getvcol() below. -/// -/// @param p -/// @param col -/// -/// @return Number of characters. -#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \ - if (*(p) == TAB && (!(wp)->w_p_list || wp->w_p_lcs_chars.tab1)) { \ - return tabstop_padding(col, (buf)->b_p_ts, (buf)->b_p_vts_array); \ - } else { \ - return ptr2cells(p); \ - } - -int chartabsize(char_u *p, colnr_T col) -{ - RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col) -} - -static int win_chartabsize(win_T *wp, char_u *p, colnr_T col) -{ - RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col) -} - -/// Return the number of characters the string 's' will take on the screen, -/// taking into account the size of a tab. -/// -/// @param s -/// -/// @return Number of characters the string will take on the screen. -int linetabsize(char_u *s) -{ - return linetabsize_col(0, s); -} - -/// Like linetabsize(), but starting at column "startcol". -/// -/// @param startcol -/// @param s -/// -/// @return Number of characters the string will take on the screen. -int linetabsize_col(int startcol, char_u *s) -{ - colnr_T col = startcol; - char_u *line = s; /* pointer to start of line, for breakindent */ - - while (*s != NUL) { - col += lbr_chartabsize_adv(line, &s, col); - } - return (int)col; -} - -/// Like linetabsize(), but for a given window instead of the current one. -/// -/// @param wp -/// @param line -/// @param len -/// -/// @return Number of characters the string will take on the screen. -unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len) -{ - colnr_T col = 0; - - for (char_u *s = line; - *s != NUL && (len == MAXCOL || s < line + len); - MB_PTR_ADV(s)) { - col += win_lbr_chartabsize(wp, line, s, col, NULL); - } - - return (unsigned int)col; -} - /// Check that "c" is a normal identifier character: /// Letters and characters from the 'isident' option. /// @@ -936,229 +863,6 @@ bool vim_isprintc_strict(int c) return c > 0 && (g_chartab[c] & CT_PRINT_CHAR); } -/// like chartabsize(), but also check for line breaks on the screen -/// -/// @param line -/// @param s -/// @param col -/// -/// @return The number of characters taken up on the screen. -int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col) -{ - if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) { - if (curwin->w_p_wrap) { - return win_nolbr_chartabsize(curwin, s, col, NULL); - } - RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col) - } - return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL); -} - -/// Call lbr_chartabsize() and advance the pointer. -/// -/// @param line -/// @param s -/// @param col -/// -/// @return The number of characters take up on the screen. -int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col) -{ - int retval; - - retval = lbr_chartabsize(line, *s, col); - MB_PTR_ADV(*s); - return retval; -} - -/// This function is used very often, keep it fast!!!! -/// -/// If "headp" not NULL, set *headp to the size of what we for 'showbreak' -/// string at start of line. Warning: *headp is only set if it's a non-zero -/// value, init to 0 before calling. -/// -/// @param wp -/// @param line -/// @param s -/// @param col -/// @param headp -/// -/// @return The number of characters taken up on the screen. -int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp) -{ - colnr_T col2; - colnr_T col_adj = 0; /* col + screen size of tab */ - colnr_T colmax; - int added; - int mb_added = 0; - int numberextra; - char_u *ps; - int n; - - // No 'linebreak', 'showbreak' and 'breakindent': return quickly. - if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) { - if (wp->w_p_wrap) { - return win_nolbr_chartabsize(wp, s, col, headp); - } - RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col) - } - - // First get normal size, without 'linebreak' - int size = win_chartabsize(wp, s, col); - int c = *s; - if (*s == TAB) { - col_adj = size - 1; - } - - // If 'linebreak' set check at a blank before a non-blank if the line - // needs a break here - if (wp->w_p_lbr - && vim_isbreak(c) - && !vim_isbreak((int)s[1]) - && wp->w_p_wrap - && (wp->w_width_inner != 0)) { - // Count all characters from first non-blank after a blank up to next - // non-blank after a blank. - numberextra = win_col_off(wp); - col2 = col; - colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); - - if (col >= colmax) { - colmax += col_adj; - n = colmax + win_col_off2(wp); - - if (n > 0) { - colmax += (((col - colmax) / n) + 1) * n - col_adj; - } - } - - for (;;) { - ps = s; - MB_PTR_ADV(s); - c = *s; - - if (!(c != NUL - && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) { - break; - } - - col2 += win_chartabsize(wp, s, col2); - - if (col2 >= colmax) { /* doesn't fit */ - size = colmax - col + col_adj; - break; - } - } - } else if ((size == 2) - && (MB_BYTE2LEN(*s) > 1) - && wp->w_p_wrap - && in_win_border(wp, col)) { - // Count the ">" in the last column. - ++size; - mb_added = 1; - } - - // May have to add something for 'breakindent' and/or 'showbreak' - // string at start of line. - // Set *headp to the size of what we add. - added = 0; - - if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) { - colnr_T sbrlen = 0; - int numberwidth = win_col_off(wp); - - numberextra = numberwidth; - col += numberextra + mb_added; - - if (col >= (colnr_T)wp->w_width_inner) { - col -= wp->w_width_inner; - numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp)); - if (col >= numberextra && numberextra > 0) { - col %= numberextra; - } - if (*p_sbr != NUL) { - sbrlen = (colnr_T)MB_CHARLEN(p_sbr); - if (col >= sbrlen) { - col -= sbrlen; - } - } - if (col >= numberextra && numberextra > 0) { - col %= numberextra; - } else if (col > 0 && numberextra > 0) { - col += numberwidth - win_col_off2(wp); - } - - numberwidth -= win_col_off2(wp); - } - - if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) { - if (*p_sbr != NUL) { - if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) { - // Calculate effective window width. - int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth; - int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col)) - : 0; - - if (width <= 0) { - width = 1; - } - added += ((size - prev_width) / width) * vim_strsize(p_sbr); - if ((size - prev_width) % width) { - // Wrapped, add another length of 'sbr'. - added += vim_strsize(p_sbr); - } - } else { - added += vim_strsize(p_sbr); - } - } - - if (wp->w_p_bri) - added += get_breakindent_win(wp, line); - - size += added; - if (col != 0) { - added = 0; - } - } - } - - if (headp != NULL) { - *headp = added + mb_added; - } - return size; -} - -/// Like win_lbr_chartabsize(), except that we know 'linebreak' is off and -/// 'wrap' is on. This means we need to check for a double-byte character that -/// doesn't fit at the end of the screen line. -/// -/// @param wp -/// @param s -/// @param col -/// @param headp -/// -/// @return The number of characters take up on the screen. -static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp) -{ - int n; - - if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { - return tabstop_padding(col, - wp->w_buffer->b_p_ts, - wp->w_buffer->b_p_vts_array); - } - n = ptr2cells(s); - - // Add one cell for a double-width character in the last column of the - // window, displayed with a ">". - if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) { - if (headp != NULL) { - *headp = 1; - } - return 3; - } - return n; -} - /// Check that virtual column "vcol" is in the rightmost column of window "wp". /// /// @param wp window diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 5d2210dc7d..d4a68adeda 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -13,6 +13,7 @@ #include "nvim/memory.h" #include "nvim/misc1.h" #include "nvim/move.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/extmark.h" #include "nvim/state.h" diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index f3000f4430..74cb9a26b7 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -30,7 +30,7 @@ void decor_init(void) /// @param src_id src_id to use or 0 to use a new src_id group, /// or -1 for ungrouped highlight. /// @param hl_id Highlight group id -/// @param pos_start Cursor position to start the hightlighting at +/// @param pos_start Cursor position to start the highlighting at /// @param pos_end Cursor position to end the highlighting at /// @param offset Move the whole highlighting this many columns to the right void bufhl_add_hl_pos_offset(buf_T *buf, @@ -119,7 +119,7 @@ void clear_virttext(VirtText *text) *text = (VirtText)KV_INITIAL_VALUE; } -VirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id) +Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id) { MarkTreeIter itr[1] = { 0 }; marktree_itr_get(buf->b_marktree, row, 0, itr); @@ -132,7 +132,7 @@ VirtText *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id) mark.id, false); if (item && (ns_id == 0 || ns_id == item->ns_id) && item->decor && kv_size(item->decor->virt_text)) { - return &item->decor->virt_text; + return item->decor; } marktree_itr_next(buf->b_marktree, itr); } @@ -218,6 +218,7 @@ bool decor_redraw_line(buf_T *buf, int row, DecorState *state) } state->row = row; state->col_until = -1; + state->eol_col = -1; return true; // TODO(bfredl): be more precise } @@ -230,10 +231,6 @@ static void decor_add(DecorState *state, int start_row, int start_col, *decor, attr_id, kv_size(decor->virt_text) && owned, -1 }; - if (decor->virt_text_pos == kVTEndOfLine) { - range.win_col = -2; // handled separately - } - kv_pushp(state->active); size_t index; for (index = kv_size(state->active)-1; index > 0; index--) { @@ -345,29 +342,22 @@ void decor_redraw_end(DecorState *state) state->buf = NULL; } -VirtText decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr, - bool *aligned) +bool decor_redraw_eol(buf_T *buf, DecorState *state, int *eol_attr, int eol_col) { decor_redraw_col(buf, MAXCOL, MAXCOL, false, state); - VirtText text = VIRTTEXT_EMPTY; + state->eol_col = eol_col; + bool has_virttext = false; for (size_t i = 0; i < kv_size(state->active); i++) { DecorRange item = kv_A(state->active, i); if (item.start_row == state->row && kv_size(item.decor.virt_text)) { - if (!kv_size(text) && item.decor.virt_text_pos == kVTEndOfLine) { - text = item.decor.virt_text; - } else if (item.decor.virt_text_pos == kVTRightAlign - || item.decor.virt_text_pos == kVTWinCol) { - *aligned = true; - } + has_virttext = true; } - if (item.decor.hl_eol && item.start_row <= state->row) { *eol_attr = hl_combine_attr(*eol_attr, item.attr_id); } } - - return text; + return has_virttext; } void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col, diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 4cebc0b731..28dabeeada 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -34,19 +34,20 @@ typedef enum { struct Decoration { - int hl_id; // highlight group VirtText virt_text; + int hl_id; // highlight group VirtTextPos virt_text_pos; - bool virt_text_hide; HlMode hl_mode; + bool virt_text_hide; bool hl_eol; + bool shared; // shared decoration, don't free // TODO(bfredl): style, signs, etc DecorPriority priority; - bool shared; // shared decoration, don't free int col; // fixed col value, like win_col + int virt_text_width; // width of virt_text }; -#define DECORATION_INIT { 0, KV_INITIAL_VALUE, kVTEndOfLine, false, \ - kHlModeUnknown, false, DECOR_PRIORITY_BASE, false, 0 } +#define DECORATION_INIT { KV_INITIAL_VALUE, 0, kVTEndOfLine, kHlModeUnknown, \ + false, false, false, DECOR_PRIORITY_BASE, 0, 0 } typedef struct { int start_row; @@ -67,6 +68,8 @@ typedef struct { int row; int col_until; int current; + + int eol_col; VirtText *virt_text; } DecorState; diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 5f8b81822b..299175b28c 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1334,9 +1334,9 @@ static void set_diff_option(win_T *wp, int value) curwin = wp; curbuf = curwin->w_buffer; - curbuf_lock++; + curbuf->b_ro_locked++; set_option_value("diff", (long)value, NULL, OPT_LOCAL); - curbuf_lock--; + curbuf->b_ro_locked--; curwin = old_curwin; curbuf = curwin->w_buffer; } @@ -1869,7 +1869,7 @@ int diff_check(win_T *wp, linenr_T lnum) /// @param idx1 first entry in diff "dp" /// @param idx2 second entry in diff "dp" /// -/// @return true if two entires are equal. +/// @return true if two entries are equal. static bool diff_equal_entry(diff_T *dp, int idx1, int idx2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { @@ -2603,7 +2603,7 @@ void ex_diffgetput(exarg_T *eap) // FileChangedRO autocommand, which may do nasty things and mess // everything up. if (!curbuf->b_changed) { - change_warning(0); + change_warning(curbuf, 0); if (diff_buf_idx(curbuf) != idx_to) { EMSG(_("E787: Buffer changed unexpectedly")); goto theend; @@ -2669,7 +2669,7 @@ void ex_diffgetput(exarg_T *eap) } } - buf_empty = BUFEMPTY(); + buf_empty = buf_is_empty(curbuf); added = 0; for (i = 0; i < count; ++i) { diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index dd32cef1e3..07e484c178 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1502,10 +1502,10 @@ char_u *get_digraph_for_char(int val_arg) /// Get a digraph. Used after typing CTRL-K on the command line or in normal /// mode. /// -/// @param cmdline TRUE when called from the cmdline +/// @param cmdline true when called from the cmdline /// /// @returns composed character, or NUL when ESC was used. -int get_digraph(int cmdline) +int get_digraph(bool cmdline) { int cc; no_mapping++; diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 1579f3ff98..fec8da2c3c 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -41,6 +41,7 @@ #include "nvim/option.h" #include "nvim/path.h" #include "nvim/popupmnu.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" @@ -467,7 +468,7 @@ static void insert_enter(InsertState *s) } if (!p_im && did_restart_edit == 0) { - change_warning(s->i == 0 ? 0 : s->i + 1); + change_warning(curbuf, s->i == 0 ? 0 : s->i + 1); } ui_cursor_shape(); // may show different cursor shape @@ -2453,7 +2454,7 @@ static int ins_compl_add(char_u *const str, int len, /// /// @param match completion match /// @param str character string to check -/// @param len lenth of "str" +/// @param len length of "str" static bool ins_compl_equal(compl_T *match, char_u *str, size_t len) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { @@ -7187,7 +7188,7 @@ static void replace_do_bs(int limit_col) // Get the number of screen cells used by the character we are // going to delete. getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL); - orig_vcols = chartabsize(get_cursor_pos_ptr(), start_vcol); + orig_vcols = win_chartabsize(curwin, get_cursor_pos_ptr(), start_vcol); } (void)del_char_after_col(limit_col); if (l_State & VREPLACE_FLAG) { @@ -7201,8 +7202,8 @@ static void replace_do_bs(int limit_col) p = get_cursor_pos_ptr(); ins_len = (int)STRLEN(p) - orig_len; vcol = start_vcol; - for (i = 0; i < ins_len; ++i) { - vcol += chartabsize(p + i, vcol); + for (i = 0; i < ins_len; i++) { + vcol += win_chartabsize(curwin, p + i, vcol); i += (*mb_ptr2len)(p) - 1; } vcol -= start_vcol; @@ -8024,7 +8025,7 @@ static void ins_bs_one(colnr_T *vcolp) /// Handle Backspace, delete-word and delete-line in Insert mode. /// -/// @param c charcter that was typed +/// @param c character that was typed /// @param mode backspace mode to use /// @param[in,out] inserted_space_p whether a space was the last // character inserted @@ -8047,7 +8048,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // can't backup past first character in buffer // can't backup past starting point unless 'backspace' > 1 // can backup to a previous line if 'backspace' == 0 - if (BUFEMPTY() + if (buf_is_empty(curbuf) || (!revins_on && ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0) || (!can_bs(BS_START) @@ -8251,7 +8252,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) ins_bs_one(&vcol); } } else { - // Delete upto starting point, start of line or previous word. + // Delete up to starting point, start of line or previous word. int prev_cclass = 0; int cclass = mb_get_class(get_cursor_pos_ptr()); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ff019d1e07..789936fdff 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8151,7 +8151,7 @@ void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val) /// /// @param[in] idx Index of variable to set. /// @param[in] val Value to set to. Will be copied. -/// @param[in] len Legth of that value or -1 in which case strlen() will be +/// @param[in] len Length of that value or -1 in which case strlen() will be /// used. void set_vim_var_string(const VimVarIndex idx, const char *const val, const ptrdiff_t len) @@ -8957,7 +8957,7 @@ static void set_var_const(const char *name, const size_t name_len, const char *const val = tv_get_string(tv); // Careful: when assigning to v:errmsg and tv_get_string() - // causes an error message the variable will alrady be set. + // causes an error message the variable will already be set. if (v->di_tv.vval.v_string == NULL) { v->di_tv.vval.v_string = (char_u *)xstrdup(val); } diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 33c6fae5cf..eb20cd1bc8 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -136,6 +136,7 @@ return { getchar={args={0, 1}}, getcharmod={}, getcharsearch={}, + getcharstr={args={0, 1}}, getcmdline={}, getcmdpos={}, getcmdtype={}, diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index bbba9d12f2..8ac2c3b8eb 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -16,7 +16,7 @@ static char *e_letwrong = N_("E734: Wrong variable type for %s="); char *e_listidx = N_("E684: list index out of range: %" PRId64); -/// Hanle tv1 += tv2, -=, *=, /=, %=, .= +/// Handle tv1 += tv2, -=, *=, /=, %=, .= /// /// @param[in,out] tv1 First operand, modified typval. /// @param[in] tv2 Second operand. diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 1ba31bfe68..4e409cca50 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -47,6 +47,7 @@ #include "nvim/os/input.h" #include "nvim/os/shell.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/popupmnu.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" @@ -1055,8 +1056,10 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (virtual_active() && fp == &curwin->w_cursor) { char_u *p = get_cursor_pos_ptr(); - if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, - curwin->w_virtcol - curwin->w_cursor.coladd)) { + if (curwin->w_cursor.coladd + >= (colnr_T)win_chartabsize(curwin, p, + (curwin->w_virtcol + - curwin->w_cursor.coladd))) { int l; if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) @@ -1078,10 +1081,11 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - /* Check for undo allowed here, because if something was already inserted - * the line was already saved for undo and this check isn't done. */ - if (!undo_allowed()) + // Check for undo allowed here, because if something was already inserted + // the line was already saved for undo and this check isn't done. + if (!undo_allowed(curbuf)) { return; + } if (argvars[1].v_type != VAR_LIST) { EMSG(_(e_invarg)); @@ -1921,7 +1925,7 @@ static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (expr_start != NULL && !aborting()) { EMSG2(_(e_invexpr2), expr_start); } - need_clr_eos = FALSE; + need_clr_eos = false; rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; } else if (*s != NUL) { @@ -3027,10 +3031,9 @@ static void f_getchangelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/* - * "getchar()" function - */ -static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +// "getchar()" and "getcharstr()" functions +static void getchar_common(typval_T *argvars, typval_T *rettv) + FUNC_ATTR_NONNULL_ALL { varnumber_T n; bool error = false; @@ -3097,6 +3100,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { i += utf_char2bytes(n, temp + i); } + assert(i < 10); temp[i++] = NUL; rettv->v_type = VAR_STRING; rettv->vval.v_string = vim_strsave(temp); @@ -3105,15 +3109,14 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) int row = mouse_row; int col = mouse_col; int grid = mouse_grid; - win_T *win; linenr_T lnum; win_T *wp; int winnr = 1; if (row >= 0 && col >= 0) { - /* Find the window at the mouse coordinates and compute the - * text position. */ - win = mouse_find_win(&grid, &row, &col); + // Find the window at the mouse coordinates and compute the + // text position. + win_T *const win = mouse_find_win(&grid, &row, &col); if (win == NULL) { return; } @@ -3129,6 +3132,32 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +// "getchar()" function +static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + getchar_common(argvars, rettv); +} + +// "getcharstr()" function +static void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + getchar_common(argvars, rettv); + + if (rettv->v_type == VAR_NUMBER) { + char_u temp[7]; // mbyte-char: 6, NUL: 1 + const varnumber_T n = rettv->vval.v_number; + int i = 0; + + if (n != 0) { + i += utf_char2bytes(n, temp); + } + assert(i < 7); + temp[i++] = NUL; + rettv->v_type = VAR_STRING; + rettv->vval.v_string = vim_strsave(temp); + } +} + /* * "getcharmod()" function */ @@ -5181,6 +5210,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool pty = false; bool clear_env = false; bool overlapped = false; + ChannelStdinMode stdin_mode = kChannelStdinPipe; CallbackReader on_stdout = CALLBACK_READER_INIT, on_stderr = CALLBACK_READER_INIT; Callback on_exit = CALLBACK_NONE; @@ -5195,6 +5225,17 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) clear_env = tv_dict_get_number(job_opts, "clear_env") != 0; overlapped = tv_dict_get_number(job_opts, "overlapped") != 0; + char *s = tv_dict_get_string(job_opts, "stdin", false); + if (s) { + if (!strncmp(s, "null", NUMBUFLEN)) { + stdin_mode = kChannelStdinNull; + } else if (!strncmp(s, "pipe", NUMBUFLEN)) { + // Nothing to do, default value + } else { + EMSG3(_(e_invargNval), "stdin", s); + } + } + if (pty && rpc) { EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set"); shell_free_argv(argv); @@ -5251,8 +5292,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) env = create_environment(job_env, clear_env, pty, term_name); Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty, - rpc, overlapped, detach, cwd, width, height, - env, &rettv->vval.v_number); + rpc, overlapped, detach, stdin_mode, cwd, + width, height, env, &rettv->vval.v_number); if (chan) { channel_create_event(chan, NULL); } @@ -7732,8 +7773,9 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT, CALLBACK_READER_INIT, CALLBACK_NONE, - false, true, false, false, NULL, 0, 0, - NULL, &rettv->vval.v_number); + false, true, false, false, + kChannelStdinPipe, NULL, 0, 0, NULL, + &rettv->vval.v_number); if (chan) { channel_create_event(chan, NULL); } @@ -10849,10 +10891,11 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) const bool rpc = false; const bool overlapped = false; const bool detach = false; + ChannelStdinMode stdin_mode = kChannelStdinPipe; uint16_t term_width = MAX(0, curwin->w_width_inner - win_col_off(curwin)); Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, - pty, rpc, overlapped, detach, cwd, - term_width, curwin->w_height_inner, + pty, rpc, overlapped, detach, stdin_mode, + cwd, term_width, curwin->w_height_inner, env, &rettv->vval.v_number); if (rettv->vval.v_number <= 0) { return; @@ -11352,6 +11395,9 @@ static void f_win_gettype(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = vim_strsave((char_u *)"popup"); } else if (wp == curwin && cmdwin_type != 0) { rettv->vval.v_string = vim_strsave((char_u *)"command"); + } else if (bt_quickfix(wp->w_buffer)) { + rettv->vval.v_string = vim_strsave((char_u *)(wp->w_llist_ref != NULL ? + "loclist" : "quickfix")); } } diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 7221dc8bc9..5cb0058ec6 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -836,7 +836,7 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep) return retval; } -/// Chech whether two lists are equal +/// Check whether two lists are equal /// /// @param[in] l1 First list to compare. /// @param[in] l2 Second list to compare. diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 050b84efec..ef49fa1de6 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -55,7 +55,7 @@ enum ListLenSpecials { #define VARNUMBER_MAX INT64_MAX #define UVARNUMBER_MAX UINT64_MAX -/// Mimimal possible value of varnumber_T variable +/// Minimal possible value of varnumber_T variable #define VARNUMBER_MIN INT64_MIN /// %d printf format specifier for varnumber_T @@ -322,7 +322,7 @@ struct ufunc { int uf_prof_initialized; // Managing cfuncs cfunc_T uf_cb; ///< C function extension callback - cfunc_free_T uf_cb_free; ///< C function extesion free callback + cfunc_free_T uf_cb_free; ///< C function extension free callback void *uf_cb_state; ///< State of C function extension. // Profiling the function as a whole. int uf_tm_count; ///< nr of calls diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 5ffc06ec44..deddec413b 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -1902,7 +1902,7 @@ void ex_function(exarg_T *eap) char_u *line_to_free = NULL; int c; int saved_did_emsg; - int saved_wait_return = need_wait_return; + bool saved_wait_return = need_wait_return; char_u *name = NULL; char_u *p; char_u *arg; @@ -3029,13 +3029,13 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) current_funccal->returned = false; } - /* - * Cleanup (and inactivate) conditionals, but stop when a try conditional - * not in its finally clause (which then is to be executed next) is found. - * In this case, make the ":return" pending for execution at the ":endtry". - * Otherwise, return normally. - */ - idx = cleanup_conditionals(eap->cstack, 0, TRUE); + // + // Cleanup (and deactivate) conditionals, but stop when a try conditional + // not in its finally clause (which then is to be executed next) is found. + // In this case, make the ":return" pending for execution at the ":endtry". + // Otherwise, return normally. + // + idx = cleanup_conditionals(eap->cstack, 0, true); if (idx >= 0) { cstack->cs_pending[idx] = CSTP_RETURN; @@ -3459,54 +3459,54 @@ dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen, /// Set "copyID + 1" in previous_funccal and callers. bool set_ref_in_previous_funccal(int copyID) { - bool abort = false; - - for (funccall_T *fc = previous_funccal; !abort && fc != NULL; + for (funccall_T *fc = previous_funccal; fc != NULL; fc = fc->caller) { fc->fc_copyID = copyID + 1; - abort = abort - || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL) - || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL) - || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL); + if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL) + || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL) + || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL)) { + return true; + } } - return abort; + return false; } static bool set_ref_in_funccal(funccall_T *fc, int copyID) { - bool abort = false; - if (fc->fc_copyID != copyID) { fc->fc_copyID = copyID; - abort = abort - || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL) - || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL) - || set_ref_in_list(&fc->l_varlist, copyID, NULL) - || set_ref_in_func(NULL, fc->func, copyID); + if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL) + || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL) + || set_ref_in_list(&fc->l_varlist, copyID, NULL) + || set_ref_in_func(NULL, fc->func, copyID)) { + return true; + } } - return abort; + return false; } /// Set "copyID" in all local vars and arguments in the call stack. bool set_ref_in_call_stack(int copyID) { - bool abort = false; - - for (funccall_T *fc = current_funccal; !abort && fc != NULL; + for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->caller) { - abort = abort || set_ref_in_funccal(fc, copyID); + if (set_ref_in_funccal(fc, copyID)) { + return true; + } } // Also go through the funccal_stack. - for (funccal_entry_T *entry = funccal_stack; !abort && entry != NULL; + for (funccal_entry_T *entry = funccal_stack; entry != NULL; entry = entry->next) { - for (funccall_T *fc = entry->top_funccal; !abort && fc != NULL; + for (funccall_T *fc = entry->top_funccal; fc != NULL; fc = fc->caller) { - abort = abort || set_ref_in_funccal(fc, copyID); + if (set_ref_in_funccal(fc, copyID)) { + return true; + } } } - return abort; + return false; } /// Set "copyID" in all functions available by name. @@ -3514,7 +3514,6 @@ bool set_ref_in_functions(int copyID) { int todo; hashitem_T *hi = NULL; - bool abort = false; ufunc_T *fp; todo = (int)func_hashtab.ht_used; @@ -3522,24 +3521,25 @@ bool set_ref_in_functions(int copyID) if (!HASHITEM_EMPTY(hi)) { todo--; fp = HI2UF(hi); - if (!func_name_refcount(fp->uf_name)) { - abort = abort || set_ref_in_func(NULL, fp, copyID); + if (!func_name_refcount(fp->uf_name) + && set_ref_in_func(NULL, fp, copyID)) { + return true; } } } - return abort; + return false; } /// Set "copyID" in all function arguments. bool set_ref_in_func_args(int copyID) { - bool abort = false; - for (int i = 0; i < funcargs.ga_len; i++) { - abort = abort || set_ref_in_item(((typval_T **)funcargs.ga_data)[i], - copyID, NULL, NULL); + if (set_ref_in_item(((typval_T **)funcargs.ga_data)[i], + copyID, NULL, NULL)) { + return true; + } } - return abort; + return false; } /// Mark all lists and dicts referenced through function "name" with "copyID". diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 1e9e530a42..a8ded66ea5 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -19,7 +19,7 @@ # include "event/stream.c.generated.h" #endif -// For compatbility with libuv < 1.19.0 (tested on 1.18.0) +// For compatibility with libuv < 1.19.0 (tested on 1.18.0) #if UV_VERSION_MINOR < 19 #define uv_stream_get_write_queue_size(stream) stream->write_queue_size #endif diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 4af7794317..041140211e 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -55,6 +55,7 @@ #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" @@ -103,7 +104,7 @@ typedef struct { // the preview window typedef struct { kvec_t(SubResult) subresults; - linenr_T lines_needed; // lines neede in the preview window + linenr_T lines_needed; // lines needed in the preview window } PreviewLines; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -828,7 +829,7 @@ void ex_retab(exarg_T *eap) } if (ptr[col] == NUL) break; - vcol += chartabsize(ptr + col, (colnr_T)vcol); + vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol); col += utfc_ptr2len(ptr + col); } if (new_line == NULL) /* out of memory */ @@ -1635,14 +1636,14 @@ void print_line(linenr_T lnum, int use_number, int list) msg_start(); silent_mode = FALSE; - info_message = TRUE; /* use mch_msg(), not mch_errmsg() */ + info_message = true; // use mch_msg(), not mch_errmsg() print_line_no_prefix(lnum, use_number, list); if (save_silent) { msg_putchar('\n'); ui_flush(); silent_mode = save_silent; } - info_message = FALSE; + info_message = false; } int rename_buffer(char_u *new_fname) @@ -1892,7 +1893,7 @@ int do_write(exarg_T *eap) if (eap->cmdidx == CMD_saveas) { if (retval == OK) { curbuf->b_p_ro = FALSE; - redraw_tabline = TRUE; + redraw_tabline = true; } } @@ -2607,7 +2608,7 @@ int do_ecmd( && (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur)) { // Sync first so that this is a separate undo-able action. u_sync(false); - if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, true) + if (u_savecommon(curbuf, 0, curbuf->b_ml.ml_line_count + 1, 0, true) == FAIL) { xfree(new_name); goto theend; @@ -2812,8 +2813,9 @@ int do_ecmd( redraw_curbuf_later(NOT_VALID); // redraw this buffer later } - if (p_im) - need_start_insertmode = TRUE; + if (p_im) { + need_start_insertmode = true; + } /* Change directories when the 'acd' option is set. */ do_autochdir(); @@ -2879,7 +2881,7 @@ void ex_append(exarg_T *eap) for (;; ) { msg_scroll = TRUE; - need_wait_return = FALSE; + need_wait_return = false; if (curbuf->b_p_ai) { if (append_indent >= 0) { indent = append_indent; @@ -2887,7 +2889,6 @@ void ex_append(exarg_T *eap) } else if (lnum > 0) indent = get_indent_lnum(lnum); } - ex_keep_indent = FALSE; if (eap->getline == NULL) { /* No getline() function, use the lines that follow. This ends * when there is no more. */ @@ -2915,10 +2916,6 @@ void ex_append(exarg_T *eap) if (theline == NULL) break; - /* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */ - if (ex_keep_indent) - append_indent = indent; - /* Look for the "." after automatic indent. */ vcol = 0; for (p = theline; indent > vcol; ++p) { @@ -2972,8 +2969,8 @@ void ex_append(exarg_T *eap) check_cursor_lnum(); beginline(BL_SOL | BL_FIX); - need_wait_return = FALSE; /* don't use wait_return() now */ - ex_no_reprint = TRUE; + need_wait_return = false; // don't use wait_return() now + ex_no_reprint = true; } /* @@ -3751,6 +3748,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, */ while (subflags.do_ask) { if (exmode_active) { + char *prompt; char_u *resp; colnr_T sc, ec; @@ -3767,13 +3765,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, sc += numw; ec += numw; } - msg_start(); - for (i = 0; i < (long)sc; ++i) - msg_putchar(' '); - for (; i <= (long)ec; ++i) - msg_putchar('^'); - resp = getexmodeline('?', NULL, 0, true); + prompt = xmallocz(ec + 1); + memset(prompt, ' ', sc); + memset(prompt + sc, '^', ec - sc + 1); + resp = (char_u *)getcmdline_prompt(NUL, prompt, 0, EXPAND_NOTHING, + NULL, CALLBACK_NONE); + msg_putchar('\n'); + xfree(prompt); if (resp != NULL) { typed = *resp; xfree(resp); @@ -3823,8 +3822,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, redraw_later(curwin, SOME_VALID); curwin->w_p_fen = save_p_fen; - if (msg_row == Rows - 1) - msg_didout = FALSE; /* avoid a scroll-up */ + if (msg_row == Rows - 1) { + msg_didout = false; // avoid a scroll-up + } msg_starthere(); i = msg_scroll; msg_scroll = 0; /* truncate msg when @@ -3843,8 +3843,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, typed = plain_vgetc(); no_mapping--; - /* clear the question */ - msg_didout = FALSE; /* don't scroll up */ + // clear the question + msg_didout = false; // don't scroll up msg_col = 0; gotocmdline(true); p_lz = save_p_lz; @@ -4819,7 +4819,7 @@ char_u *check_help_lang(char_u *arg) * Return a heuristic indicating how well the given string matches. The * smaller the number, the better the match. This is the order of priorities, * from best match to worst match: - * - Match with least alpha-numeric characters is better. + * - Match with least alphanumeric characters is better. * - Match with least total characters is better. * - Match towards the start is better. * - Match starting with "+" is worse (feature instead of command) @@ -5159,9 +5159,9 @@ void fix_help_buffer(void) // Set filetype to "help". if (STRCMP(curbuf->b_p_ft, "help") != 0) { - curbuf_lock++; + curbuf->b_ro_locked++; set_option_value("ft", 0L, "help", OPT_LOCAL); - curbuf_lock--; + curbuf->b_ro_locked--; } if (!syntax_present(curwin)) { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 9d500a8ddb..a49b0c15e1 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -135,7 +135,7 @@ void do_debug(char_u *cmd) const bool save_cmd_silent = cmd_silent; int save_msg_silent = msg_silent; int save_emsg_silent = emsg_silent; - int save_redir_off = redir_off; + bool save_redir_off = redir_off; tasave_T typeaheadbuf; bool typeahead_saved = false; int save_ignore_script = 0; @@ -3501,7 +3501,7 @@ void do_finish(exarg_T *eap, int reanimate) eap->cookie))->finished = false; } - // Cleanup (and inactivate) conditionals, but stop when a try conditional + // Cleanup (and deactivate) conditionals, but stop when a try conditional // not in its finally clause (which then is to be executed next) is found. // In this case, make the ":finish" pending for execution at the ":endtry". // Otherwise, finish normally. diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index f928c61ea4..d64b14c9c5 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -58,7 +58,7 @@ #define EX_SBOXOK 0x40000 // allowed in the sandbox #define EX_CMDWIN 0x80000 // allowed in cmdline window; when missing // disallows editing another buffer when - // curbuf_lock is set + // current buffer is locked #define EX_MODIFY 0x100000 // forbidden in non-'modifiable' buffer #define EX_FLAGS 0x200000 // allow flags after count in argument #define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 27c98a13a6..3afcd9ec5a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -97,7 +97,7 @@ static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL}; #define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i]) #define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i]) -/* Wether a command index indicates a user command. */ +// Whether a command index indicates a user command. # define IS_USER_CMDIDX(idx) ((int)(idx) < 0) /* Struct for storing a line inside a while/for loop */ @@ -186,17 +186,14 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp) } /// Repeatedly get commands for Ex mode, until the ":vi" command is given. -void do_exmode(int improved) +void do_exmode(void) { int save_msg_scroll; int prev_msg_row; linenr_T prev_line; int changedtick; - if (improved) - exmode_active = EXMODE_VIM; - else - exmode_active = EXMODE_NORMAL; + exmode_active = true; State = NORMAL; /* When using ":global /pat/ visual" and then "Q" we return to continue @@ -212,7 +209,7 @@ void do_exmode(int improved) while (exmode_active) { /* Check for a ":normal" command and no more characters left. */ if (ex_normal_busy > 0 && typebuf.tb_len == 0) { - exmode_active = 0; + exmode_active = false; break; } msg_scroll = true; @@ -309,13 +306,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, /* argument for fgetline() */ int flags) { - char_u *next_cmdline; /* next cmd to execute */ - char_u *cmdline_copy = NULL; /* copy of cmd line */ - int used_getline = FALSE; /* used "fgetline" to obtain command */ - static int recursive = 0; /* recursive depth */ - int msg_didout_before_start = 0; - int count = 0; /* line number count */ - int did_inc = FALSE; /* incremented RedrawingDisabled */ + char_u *next_cmdline; // next cmd to execute + char_u *cmdline_copy = NULL; // copy of cmd line + bool used_getline = false; // used "fgetline" to obtain command + static int recursive = 0; // recursive depth + bool msg_didout_before_start = false; + int count = 0; // line number count + int did_inc = FALSE; // incremented RedrawingDisabled int retval = OK; cstack_T cstack = { // conditional stack .cs_idx = -1, @@ -535,7 +532,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, retval = FAIL; break; } - used_getline = TRUE; + used_getline = true; /* * Keep the first typed line. Clear it when more lines are typed. @@ -565,7 +562,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, && (cstack.cs_looplevel || has_loop_cmd(next_cmdline))) { store_loop_line(&lines_ga, next_cmdline); } - did_endif = FALSE; + did_endif = false; if (count++ == 0) { /* @@ -576,7 +573,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, */ if (!(flags & DOCMD_NOWAIT) && !recursive) { msg_didout_before_start = msg_didout; - msg_didany = FALSE; /* no output yet */ + msg_didany = false; // no output yet msg_start(); msg_scroll = TRUE; /* put messages below each other */ ++no_wait_return; /* don't wait for return until finished */ @@ -750,14 +747,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, * the :endtry to be missed. */ && (cstack.cs_trylevel == 0 || did_emsg_syntax) && used_getline - && (getline_equal(fgetline, cookie, getexmodeline) - || getline_equal(fgetline, cookie, getexline))) + && getline_equal(fgetline, cookie, getexline)) && (next_cmdline != NULL || cstack.cs_idx >= 0 || (flags & DOCMD_REPEAT))); xfree(cmdline_copy); - did_emsg_syntax = FALSE; + did_emsg_syntax = false; GA_DEEP_CLEAR(&lines_ga, wcmd_T, FREE_WCMD); if (cstack.cs_idx >= 0) { @@ -931,8 +927,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, if (retval == FAIL || (did_endif && KeyTyped && !did_emsg) ) { - need_wait_return = FALSE; - msg_didany = FALSE; /* don't wait when restarting edit */ + need_wait_return = false; + msg_didany = false; // don't wait when restarting edit } else if (need_wait_return) { /* * The msg_start() above clears msg_didout. The wait_return we do @@ -944,7 +940,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, } } - did_endif = FALSE; /* in case do_cmdline used recursively */ + did_endif = false; // in case do_cmdline used recursively call_depth--; end_batch_changes(); @@ -1518,7 +1514,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, goto doend; } - // Disallow editing another buffer when "curbuf_lock" is set. + // Disallow editing another buffer when "curbuf->b_ro_locked" is set. // Do allow ":checktime" (it is postponed). // Do allow ":edit" (check for an argument later). // Do allow ":file" with no arguments (check for an argument later). @@ -1601,7 +1597,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, else ea.arg = skipwhite(p); - // ":file" cannot be run with an argument when "curbuf_lock" is set + // ":file" cannot be run with an argument when "curbuf->b_ro_locked" is set if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) { goto doend; } @@ -2056,8 +2052,7 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only) // in ex mode, an empty line works like :+ if (*eap->cmd == NUL && exmode_active - && (getline_equal(eap->getline, eap->cookie, getexmodeline) - || getline_equal(eap->getline, eap->cookie, getexline)) + && getline_equal(eap->getline, eap->cookie, getexline) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { eap->cmd = (char_u *)"+"; if (!skip_only) { @@ -2956,12 +2951,13 @@ const char * set_one_cmd_context( } } - /* - * If the cursor is touching the command, and it ends in an alpha-numeric - * character, complete the command name. - */ - if (*p == NUL && ASCII_ISALNUM(p[-1])) + // + // If the cursor is touching the command, and it ends in an alphanumeric + // character, complete the command name. + // + if (*p == NUL && ASCII_ISALNUM(p[-1])) { return NULL; + } if (ea.cmdidx == CMD_SIZE) { if (*cmd == 's' && vim_strchr((const char_u *)"cgriI", cmd[1]) != NULL) { @@ -5518,6 +5514,9 @@ invalid_count: return OK; } +static char e_complete_used_without_nargs[] = N_( + "E1208: -complete used without -nargs"); + /* * ":command ..." */ @@ -5569,10 +5568,10 @@ static void ex_command(exarg_T *eap) uc_list(name, end - name); } else if (!ASCII_ISUPPER(*name)) { EMSG(_("E183: User defined commands must start with an uppercase letter")); - return; } else if (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0) { EMSG(_("E841: Reserved name, cannot be used for user defined command")); - return; + } else if (compl > 0 && (argt & EX_EXTRA) == 0) { + EMSG(_(e_complete_used_without_nargs)); } else { uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, addr_type_arg, eap->forceit); @@ -6656,9 +6655,10 @@ void tabpage_close_other(tabpage_T *tp, int forceit) break; } - redraw_tabline = TRUE; - if (h != tabline_height()) + redraw_tabline = true; + if (h != tabline_height()) { shell_new_rows(); + } } /* @@ -6802,7 +6802,7 @@ static void ex_print(exarg_T *eap) beginline(BL_SOL | BL_FIX); } - ex_no_reprint = TRUE; + ex_no_reprint = true; } static void ex_goto(exarg_T *eap) @@ -7302,7 +7302,7 @@ do_exedit( */ if (exmode_active && (eap->cmdidx == CMD_visual || eap->cmdidx == CMD_view)) { - exmode_active = 0; + exmode_active = false; ex_pressedreturn = false; if (*eap->arg == NUL) { /* Special case: ":global/pat/visual\NLvi-commands" */ @@ -7318,7 +7318,7 @@ do_exedit( RedrawingDisabled = 0; no_wait_return = 0; - need_wait_return = FALSE; + need_wait_return = false; msg_scroll = 0; redraw_all_later(NOT_VALID); @@ -7344,16 +7344,18 @@ do_exedit( old_curwin == NULL ? curwin : NULL); } else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit) || *eap->arg != NUL) { - /* Can't edit another file when "curbuf_lock" is set. Only ":edit" - * can bring us here, others are stopped earlier. */ - if (*eap->arg != NUL && curbuf_locked()) + // Can't edit another file when "curbuf->b_ro_lockec" is set. Only ":edit" + // can bring us here, others are stopped earlier. + if (*eap->arg != NUL && curbuf_locked()) { return; + } n = readonlymode; - if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview) - readonlymode = TRUE; - else if (eap->cmdidx == CMD_enew) - readonlymode = FALSE; /* 'readonly' doesn't make sense in an - empty buffer */ + if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview) { + readonlymode = true; + } else if (eap->cmdidx == CMD_enew) { + readonlymode = false; // 'readonly' doesn't make sense + // in an empty buffer + } if (eap->cmdidx != CMD_balt && eap->cmdidx != CMD_badd) { setpcmark(); } @@ -7412,7 +7414,7 @@ do_exedit( && !cmdmod.keepalt) old_curwin->w_alt_fnum = curbuf->b_fnum; - ex_no_reprint = TRUE; + ex_no_reprint = true; } /// ":gui" and ":gvim" when there is no GUI. @@ -7488,7 +7490,7 @@ static void ex_syncbind(exarg_T *eap) curwin = save_curwin; curbuf = save_curbuf; if (curwin->w_p_scb) { - did_syncbind = TRUE; + did_syncbind = true; checkpcmark(); if (old_linenr != curwin->w_cursor.lnum) { char_u ctrl_o[2]; @@ -7911,8 +7913,8 @@ void ex_may_print(exarg_T *eap) { if (eap->flags != 0) { print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR), - (eap->flags & EXFLAG_LIST)); - ex_no_reprint = TRUE; + (eap->flags & EXFLAG_LIST)); + ex_no_reprint = true; } } @@ -7967,9 +7969,9 @@ static void ex_at(exarg_T *eap) == FAIL) { beep_flush(); } else { - int save_efr = exec_from_reg; + bool save_efr = exec_from_reg; - exec_from_reg = TRUE; + exec_from_reg = true; /* * Execute from the typeahead buffer. @@ -8007,16 +8009,16 @@ static void ex_wundo(exarg_T *eap) { char_u hash[UNDO_HASH_SIZE]; - u_compute_hash(hash); - u_write_undo((char *) eap->arg, eap->forceit, curbuf, hash); + u_compute_hash(curbuf, hash); + u_write_undo((char *)eap->arg, eap->forceit, curbuf, hash); } static void ex_rundo(exarg_T *eap) { char_u hash[UNDO_HASH_SIZE]; - u_compute_hash(hash); - u_read_undo((char *) eap->arg, hash, NULL); + u_compute_hash(curbuf, hash); + u_read_undo((char *)eap->arg, hash, NULL); } /// ":redo". @@ -8133,7 +8135,7 @@ static void ex_redir(exarg_T *eap) if (redir_fd != NULL || redir_reg || redir_vname ) - redir_off = FALSE; + redir_off = false; } /// ":redraw": force redraw @@ -8160,12 +8162,12 @@ static void ex_redraw(exarg_T *eap) RedrawingDisabled = r; p_lz = p; - /* Reset msg_didout, so that a message that's there is overwritten. */ - msg_didout = FALSE; + // Reset msg_didout, so that a message that's there is overwritten. + msg_didout = false; msg_col = 0; - /* No need to wait after an intentional redraw. */ - need_wait_return = FALSE; + // No need to wait after an intentional redraw. + need_wait_return = false; ui_flush(); } @@ -8348,7 +8350,9 @@ void restore_current_state(save_state_T *sst) finish_op = sst->save_finish_op; opcount = sst->save_opcount; reg_executing = sst->save_reg_executing; - msg_didout |= sst->save_msg_didout; // don't reset msg_didout now + + // don't reset msg_didout now + msg_didout |= sst->save_msg_didout; // Restore the state (needed when called from a function executed for // 'indentexpr'). Update the mouse and cursor, they may have changed. diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index f6bd2adcd5..292e01dd6b 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -16,16 +16,12 @@ #define VALID_PATH 1 #define VALID_HEAD 2 -/* Values for exmode_active (0 is no exmode) */ -#define EXMODE_NORMAL 1 -#define EXMODE_VIM 2 - // Structure used to save the current state. Used when executing Normal mode // commands while in any other mode. typedef struct { int save_msg_scroll; int save_restart_edit; - int save_msg_didout; + bool save_msg_didout; int save_State; int save_insertmode; bool save_finish_op; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 5ca88002f1..1ceccac2bb 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -210,7 +210,7 @@ bool cause_errthrow(const char_u *mesg, bool severe, bool *ignore) * not skipped. Errors in those commands may affect what of the subsequent * commands are regarded part of catch and finally clauses. Catching the * exception would then cause execution of commands not intended by the - * user, who wouldn't even get aware of the problem. Therefor, discard the + * user, who wouldn't even get aware of the problem. Therefore, discard the * exception currently being thrown to prevent it from being caught. Just * execute finally clauses and terminate. */ @@ -832,24 +832,23 @@ void ex_if(exarg_T *eap) */ void ex_endif(exarg_T *eap) { - did_endif = TRUE; + did_endif = true; if (eap->cstack->cs_idx < 0 || (eap->cstack->cs_flags[eap->cstack->cs_idx] - & (CSF_WHILE | CSF_FOR | CSF_TRY))) + & (CSF_WHILE | CSF_FOR | CSF_TRY))) { eap->errmsg = (char_u *)N_("E580: :endif without :if"); - else { - /* - * When debugging or a breakpoint was encountered, display the debug - * prompt (if not already done). This shows the user that an ":endif" - * is executed when the ":if" or a previous ":elseif" was not TRUE. - * Handle a ">quit" debug command as if an interrupt had occurred before - * the ":endif". That is, throw an interrupt exception if appropriate. - * Doing this here prevents an exception for a parsing error being - * discarded by throwing the interrupt exception later on. - */ + } else { + // When debugging or a breakpoint was encountered, display the debug + // prompt (if not already done). This shows the user that an ":endif" + // is executed when the ":if" or a previous ":elseif" was not TRUE. + // Handle a ">quit" debug command as if an interrupt had occurred before + // the ":endif". That is, throw an interrupt exception if appropriate. + // Doing this here prevents an exception for a parsing error being + // discarded by throwing the interrupt exception later on. if (!(eap->cstack->cs_flags[eap->cstack->cs_idx] & CSF_TRUE) - && dbg_check_skipped(eap)) + && dbg_check_skipped(eap)) { (void)do_intthrow(eap->cstack); + } --eap->cstack->cs_idx; } @@ -1022,7 +1021,7 @@ void ex_continue(exarg_T *eap) else { /* Try to find the matching ":while". This might stop at a try * conditional not in its finally clause (which is then to be executed - * next). Therefor, inactivate all conditionals except the ":while" + * next). Therefore, deactivate all conditionals except the ":while" * itself (if reached). */ idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE); assert(idx >= 0); @@ -1051,14 +1050,14 @@ void ex_break(exarg_T *eap) int idx; cstack_T *const cstack = eap->cstack; - if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) + if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) { eap->errmsg = (char_u *)N_("E587: :break without :while or :for"); - else { - /* Inactivate conditionals until the matching ":while" or a try - * conditional not in its finally clause (which is then to be - * executed next) is found. In the latter case, make the ":break" - * pending for execution at the ":endtry". */ - idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE); + } else { + // Deactivate conditionals until the matching ":while" or a try + // conditional not in its finally clause (which is then to be + // executed next) is found. In the latter case, make the ":break" + // pending for execution at the ":endtry". */ + idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, true); if (idx >= 0 && !(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) { cstack->cs_pending[idx] = CSTP_BREAK; report_make_pending(CSTP_BREAK, NULL); @@ -1179,15 +1178,15 @@ void do_throw(cstack_T *cstack) int idx; int inactivate_try = FALSE; - /* - * Cleanup and inactivate up to the next surrounding try conditional that - * is not in its finally clause. Normally, do not inactivate the try - * conditional itself, so that its ACTIVE flag can be tested below. But - * if a previous error or interrupt has not been converted to an exception, - * inactivate the try conditional, too, as if the conversion had been done, - * and reset the did_emsg or got_int flag, so this won't happen again at - * the next surrounding try conditional. - */ + // + // Cleanup and deactivate up to the next surrounding try conditional that + // is not in its finally clause. Normally, do not deactivate the try + // conditional itself, so that its ACTIVE flag can be tested below. But + // if a previous error or interrupt has not been converted to an exception, + // deactivate the try conditional, too, as if the conversion had been done, + // and reset the did_emsg or got_int flag, so this won't happen again at + // the next surrounding try conditional. + // #ifndef THROW_ON_ERROR_TRUE if (did_emsg && !THROW_ON_ERROR) { inactivate_try = TRUE; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index f63987136f..af8a23f5cc 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2267,7 +2267,7 @@ static int command_line_changed(CommandLineState *s) close_preview_windows(); update_screen(SOME_VALID); // Clear 'inccommand' preview. } else { - if (s->xpc.xp_context == EXPAND_NOTHING) { + if (s->xpc.xp_context == EXPAND_NOTHING && (KeyTyped || vpeekc() == NUL)) { may_do_incsearch_highlighting(s->firstc, s->count, &s->is_state); } } @@ -2412,13 +2412,11 @@ char_u * get_text_locked_msg(void) { } } -/* - * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is - * and give an error message. - */ +/// Check if "curbuf->b_ro_locked" or "allbuf_lock" is set and +/// return TRUE when it is and give an error message. int curbuf_locked(void) { - if (curbuf_lock > 0) { + if (curbuf->b_ro_locked > 0) { EMSG(_("E788: Not allowed to edit another buffer now")); return TRUE; } @@ -2512,266 +2510,6 @@ getexline( return getcmdline(c, 1L, indent, do_concat); } -/* - * Get an Ex command line for Ex mode. - * In Ex mode we only use the OS supplied line editing features and no - * mappings or abbreviations. - * Returns a string in allocated memory or NULL. - */ -char_u * -getexmodeline( - int promptc, // normally ':', NUL for ":append" and '?' - // for :s prompt - void *cookie, - int indent, // indent for inside conditionals - bool do_concat -) -{ - garray_T line_ga; - char_u *pend; - int startcol = 0; - int c1 = 0; - int escaped = FALSE; /* CTRL-V typed */ - int vcol = 0; - char_u *p; - int prev_char; - int len; - - /* always start in column 0; write a newline if necessary */ - compute_cmdrow(); - if ((msg_col || msg_didout) && promptc != '?') - msg_putchar('\n'); - if (promptc == ':') { - /* indent that is only displayed, not in the line itself */ - if (p_prompt) - msg_putchar(':'); - while (indent-- > 0) - msg_putchar(' '); - startcol = msg_col; - } - - ga_init(&line_ga, 1, 30); - - /* autoindent for :insert and :append is in the line itself */ - if (promptc <= 0) { - vcol = indent; - while (indent >= 8) { - ga_append(&line_ga, TAB); - msg_puts(" "); - indent -= 8; - } - while (indent-- > 0) { - ga_append(&line_ga, ' '); - msg_putchar(' '); - } - } - no_mapping++; - - /* - * Get the line, one character at a time. - */ - got_int = FALSE; - while (!got_int) { - ga_grow(&line_ga, 40); - - /* Get one character at a time. Don't use inchar(), it can't handle - * special characters. */ - prev_char = c1; - - // Check for a ":normal" command and no more characters left. - if (ex_normal_busy > 0 && typebuf.tb_len == 0) { - c1 = '\n'; - } else { - c1 = vgetc(); - } - - /* - * Handle line editing. - * Previously this was left to the system, putting the terminal in - * cooked mode, but then CTRL-D and CTRL-T can't be used properly. - */ - if (got_int) { - msg_putchar('\n'); - break; - } - - if (!escaped) { - /* CR typed means "enter", which is NL */ - if (c1 == '\r') - c1 = '\n'; - - if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) { - if (!GA_EMPTY(&line_ga)) { - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - len = utf_head_off(p, p + line_ga.ga_len - 1) + 1; - line_ga.ga_len -= len; - goto redraw; - } - continue; - } - - if (c1 == Ctrl_U) { - msg_col = startcol; - msg_clr_eos(); - line_ga.ga_len = 0; - goto redraw; - } - - int num_spaces; - if (c1 == Ctrl_T) { - int sw = get_sw_value(curbuf); - - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - indent = get_indent_str(p, 8, FALSE); - num_spaces = sw - indent % sw; -add_indent: - if (num_spaces > 0) { - ga_grow(&line_ga, num_spaces + 1); - p = (char_u *)line_ga.ga_data; - char_u *s = skipwhite(p); - - // Insert spaces after leading whitespaces. - long move_len = line_ga.ga_len - (s - p) + 1; - assert(move_len >= 0); - memmove(s + num_spaces, s, (size_t)move_len); - memset(s, ' ', (size_t)num_spaces); - - line_ga.ga_len += num_spaces; - } -redraw: - /* redraw the line */ - msg_col = startcol; - vcol = 0; - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - while (p < (char_u *)line_ga.ga_data + line_ga.ga_len) { - if (*p == TAB) { - do { - msg_putchar(' '); - } while (++vcol % 8); - p++; - } else { - len = utfc_ptr2len(p); - msg_outtrans_len(p, len); - vcol += ptr2cells(p); - p += len; - } - } - msg_clr_eos(); - cmd_cursor_goto(msg_row, msg_col); - continue; - } - - if (c1 == Ctrl_D) { - /* Delete one shiftwidth. */ - p = (char_u *)line_ga.ga_data; - if (prev_char == '0' || prev_char == '^') { - if (prev_char == '^') - ex_keep_indent = TRUE; - indent = 0; - p[--line_ga.ga_len] = NUL; - } else { - p[line_ga.ga_len] = NUL; - indent = get_indent_str(p, 8, FALSE); - if (indent == 0) { - continue; - } - --indent; - indent -= indent % get_sw_value(curbuf); - } - - // reduce the line's indentation - char_u *from = skipwhite(p); - char_u *to = from; - int old_indent; - while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) { - *--to = NUL; - } - long move_len = line_ga.ga_len - (from - p) + 1; - assert(move_len > 0); - memmove(to, from, (size_t)move_len); - line_ga.ga_len -= (int)(from - to); - - // Removed to much indentation, fix it before redrawing. - num_spaces = indent - old_indent; - goto add_indent; - } - - if (c1 == Ctrl_V || c1 == Ctrl_Q) { - escaped = TRUE; - continue; - } - - if (IS_SPECIAL(c1)) { - // Ignore other special key codes - continue; - } - } - - if (IS_SPECIAL(c1)) { - c1 = '?'; - } - len = utf_char2bytes(c1, (char_u *)line_ga.ga_data + line_ga.ga_len); - if (c1 == '\n') { - msg_putchar('\n'); - } else if (c1 == TAB) { - // Don't use chartabsize(), 'ts' can be different. - do { - msg_putchar(' '); - } while (++vcol % 8); - } else { - msg_outtrans_len(((char_u *)line_ga.ga_data) + line_ga.ga_len, len); - vcol += char2cells(c1); - } - line_ga.ga_len += len; - escaped = FALSE; - - cmd_cursor_goto(msg_row, msg_col); - pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len; - - /* We are done when a NL is entered, but not when it comes after an - * odd number of backslashes, that results in a NUL. */ - if (!GA_EMPTY(&line_ga) && pend[-1] == '\n') { - int bcount = 0; - - while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\') - ++bcount; - - if (bcount > 0) { - /* Halve the number of backslashes: "\NL" -> "NUL", "\\NL" -> - * "\NL", etc. */ - line_ga.ga_len -= (bcount + 1) / 2; - pend -= (bcount + 1) / 2; - pend[-1] = '\n'; - } - - if ((bcount & 1) == 0) { - --line_ga.ga_len; - --pend; - *pend = NUL; - break; - } - } - } - - no_mapping--; - - /* make following messages go to the next line */ - msg_didout = FALSE; - msg_col = 0; - if (msg_row < Rows - 1) { - msg_row++; - } - emsg_on_display = false; // don't want os_delay() - - if (got_int) - ga_clear(&line_ga); - - return (char_u *)line_ga.ga_data; -} - bool cmdline_overstrike(void) { return ccline.overstrike; @@ -2855,7 +2593,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, ColoredCmdline *const ret_ccline_colors) FUNC_ATTR_NONNULL_ALL { - ParserLine plines[] = { + ParserLine parser_lines[] = { { .data = (const char *)colored_ccline->cmdbuff, .size = STRLEN(colored_ccline->cmdbuff), @@ -2863,7 +2601,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, }, { NULL, 0, false }, }; - ParserLine *plines_p = plines; + ParserLine *plines_p = parser_lines; ParserHighlight colors; kvi_init(colors); ParserState pstate; @@ -3717,7 +3455,7 @@ void redrawcmdline(void) { if (cmd_silent) return; - need_wait_return = FALSE; + need_wait_return = false; compute_cmdrow(); redrawcmd(); cursorcmd(); @@ -4487,13 +4225,13 @@ static int showmatches(expand_T *xp, int wildmenu) } if (!wildmenu) { - msg_didany = FALSE; /* lines_left will be set */ - msg_start(); /* prepare for paging */ + msg_didany = false; // lines_left will be set + msg_start(); // prepare for paging msg_putchar('\n'); ui_flush(); cmdline_row = msg_row; - msg_didany = FALSE; /* lines_left will be set again */ - msg_start(); /* prepare for paging */ + msg_didany = false; // lines_left will be set again + msg_start(); // prepare for paging } if (got_int) { @@ -6471,7 +6209,7 @@ static int open_cmdwin(void) char_u typestr[2]; int save_restart_edit = restart_edit; int save_State = State; - int save_exmode = exmode_active; + bool save_exmode = exmode_active; int save_cmdmsg_rl = cmdmsg_rl; /* Can't do this recursively. Can't do it when typing a password. */ @@ -6513,7 +6251,7 @@ static int open_cmdwin(void) curwin->w_p_fen = false; // Don't allow switching to another buffer. - curbuf_lock++; + curbuf->b_ro_locked++; // Showing the prompt may have set need_wait_return, reset it. need_wait_return = false; @@ -6526,7 +6264,7 @@ static int open_cmdwin(void) } set_option_value("ft", 0L, "vim", OPT_LOCAL); } - curbuf_lock--; + curbuf->b_ro_locked--; // Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin // sets 'textwidth' to 78). @@ -6565,7 +6303,7 @@ static int open_cmdwin(void) save_cmdline(&save_ccline); // No Ex mode here! - exmode_active = 0; + exmode_active = false; State = NORMAL; setmouse(); diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 67b8e7e92f..3038ed3947 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -583,22 +583,6 @@ static int makeopens(FILE *fd, char_u *dirnow) return FAIL; } - // Now put the other buffers into the buffer list. - FOR_ALL_BUFFERS(buf) { - if (!(only_save_windows && buf->b_nwindows == 0) - && !(buf->b_help && !(ssop_flags & SSOP_HELP)) - && buf->b_fname != NULL - && buf->b_p_bl) { - if (fprintf(fd, "badd +%" PRId64 " ", - buf->b_wininfo == NULL - ? (int64_t)1L - : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 - || ses_fname(fd, buf, &ssop_flags, true) == FAIL) { - return FAIL; - } - } - } - // the global argument list if (ses_arglist(fd, "argglobal", &global_alist.al_ga, !(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL) { @@ -813,12 +797,31 @@ static int makeopens(FILE *fd, char_u *dirnow) return FAIL; } + // Now put the remaining buffers into the buffer list. + // This is near the end, so that when 'hidden' is set we don't create extra + // buffers. If the buffer was already created with another command the + // ":badd" will have no effect. + FOR_ALL_BUFFERS(buf) { + if (!(only_save_windows && buf->b_nwindows == 0) + && !(buf->b_help && !(ssop_flags & SSOP_HELP)) + && buf->b_fname != NULL + && buf->b_p_bl) { + if (fprintf(fd, "badd +%" PRId64 " ", + buf->b_wininfo == NULL + ? (int64_t)1L + : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 + || ses_fname(fd, buf, &ssop_flags, true) == FAIL) { + return FAIL; + } + } + } + // // Wipe out an empty unnamed buffer we started in. // if (fprintf(fd, "%s", "if exists('s:wipebuf') " - "&& len(win_findbuf(s:wipebuf)) == 0" + "&& len(win_findbuf(s:wipebuf)) == 0 " "&& getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'\n" " silent exe 'bwipe ' . s:wipebuf\n" "endif\n" diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 2906a2196b..4b2dccd8a4 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -19,7 +19,7 @@ // Marks live in namespaces that allow plugins/users to segregate marks // from other users. // -// Deleting marks only happens when explicitly calling extmark_del, deleteing +// Deleting marks only happens when explicitly calling extmark_del, deleting // over a range of marks will only move the marks. Deleting on a mark will // leave it in same position unless it is on the EOL of a line. // @@ -268,7 +268,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id, } ExtmarkNs *my_ns = all_ns ? buf_ns_ref(buf, item.ns_id, false) : ns; map_del(uint64_t, uint64_t)(my_ns->map, item.mark_id); - map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, mark.id); + map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index, start_id); marktree_del_itr(buf->b_marktree, itr, false); } else { marktree_itr_next(buf->b_marktree, itr); diff --git a/src/nvim/extmark_defs.h b/src/nvim/extmark_defs.h index 784280dace..b5d91382ec 100644 --- a/src/nvim/extmark_defs.h +++ b/src/nvim/extmark_defs.h @@ -23,8 +23,8 @@ typedef kvec_t(ExtmarkUndoObject) extmark_undo_vec_t; typedef enum { kExtmarkNOOP, // Extmarks shouldn't be moved - kExtmarkUndo, // Operation should be reversable/undoable - kExtmarkNoUndo, // Operation should not be reversable + kExtmarkUndo, // Operation should be reversible/undoable + kExtmarkNoUndo, // Operation should not be reversible kExtmarkUndoNoRedo, // Operation should be undoable, but not redoable } ExtmarkOp; diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 29c29a2884..ee8be8429f 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -290,10 +290,10 @@ readfile( /* After reading a file the cursor line changes but we don't want to * display the line. */ - ex_no_reprint = TRUE; + ex_no_reprint = true; - /* don't display the file info for another buffer now */ - need_fileinfo = FALSE; + // don't display the file info for another buffer now + need_fileinfo = false; // For Unix: Use the short file name whenever possible. // Avoids problems with networks and when directory names are changed. @@ -2237,7 +2237,7 @@ buf_write( /* After writing a file changedtick changes but we don't want to display * the line. */ - ex_no_reprint = TRUE; + ex_no_reprint = true; /* * If there is no file name yet, use the one for the written file. @@ -4241,7 +4241,7 @@ void shorten_fnames(int force) mf_fullname(buf->b_ml.ml_mfp); } status_redraw_all(); - redraw_tabline = TRUE; + redraw_tabline = true; } /// Get new filename ended by given extension. @@ -4687,7 +4687,7 @@ check_timestamps( } if (!stuff_empty() || global_busy || !typebuf_typed() - || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0 + || autocmd_busy || curbuf->b_ro_locked > 0 || allbuf_lock > 0 ) { need_check_timestamps = true; // check later } else { @@ -4967,13 +4967,10 @@ int buf_check_timestamp(buf_T *buf) buf_reload(buf, orig_mode); if (buf->b_p_udf && buf->b_ffname != NULL) { char_u hash[UNDO_HASH_SIZE]; - buf_T *save_curbuf = curbuf; - /* Any existing undo file is unusable, write it now. */ - curbuf = buf; - u_compute_hash(hash); - u_write_undo(NULL, FALSE, buf, hash); - curbuf = save_curbuf; + // Any existing undo file is unusable, write it now. + u_compute_hash(buf, hash); + u_write_undo(NULL, false, buf, hash); } } @@ -5015,10 +5012,10 @@ void buf_reload(buf_T *buf, int orig_mode) old_topline = curwin->w_topline; if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) { - /* Save all the text, so that the reload can be undone. - * Sync first so that this is a separate undo-able action. */ - u_sync(FALSE); - saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE); + // Save all the text, so that the reload can be undone. + // Sync first so that this is a separate undo-able action. + u_sync(false); + saved = u_savecommon(curbuf, 0, curbuf->b_ml.ml_line_count + 1, 0, true); flags |= READ_KEEP_UNDO; } @@ -5027,7 +5024,7 @@ void buf_reload(buf_T *buf, int orig_mode) // buffer contents. But if reading the file fails we should keep // the old contents. Can't use memory only, the file might be // too big. Use a hidden buffer to move the buffer contents to. - if (BUFEMPTY() || saved == FAIL) { + if (buf_is_empty(curbuf) || saved == FAIL) { savebuf = NULL; } else { // Allocate a buffer without putting it in the buffer list. @@ -5060,7 +5057,7 @@ void buf_reload(buf_T *buf, int orig_mode) if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) { // Put the text back from the save buffer. First // delete any lines that readfile() added. - while (!BUFEMPTY()) { + while (!buf_is_empty(curbuf)) { if (ml_delete(buf->b_ml.ml_line_count, false) == FAIL) { break; } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index ad8418034a..6989c29d57 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -29,6 +29,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/garray.h" #include "nvim/move.h" #include "nvim/option.h" diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index d2a7c16186..1d41cabfa4 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -247,7 +247,7 @@ for i = 1, #functions do (j - 1)..'].type == kObjectTypeInteger) {') output:write('\n '..converted..' = (Float)args.items['..(j - 1)..'].data.integer;') end - -- accept empty lua tables as empty dictionarys + -- accept empty lua tables as empty dictionaries if rt:match('^Dictionary') then output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeArray && args.items['..(j - 1)..'].data.array.size == 0) {') --luacheck: ignore 631 output:write('\n '..converted..' = (Dictionary)ARRAY_DICT_INIT;') diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index d80a6219eb..9f91160034 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -69,8 +69,6 @@ local get_flags = function(o) {'alloced'}, {'nodefault'}, {'no_mkrc'}, - {'vi_def'}, - {'vim'}, {'secure'}, {'gettext'}, {'noglob'}, @@ -120,8 +118,11 @@ local get_value = function(v) return '(char_u *) ' .. value_dumpers[type(v)](v) end -local get_defaults = function(d) - return ('{' .. get_value(d.vi) .. ', ' .. get_value(d.vim) .. '}') +local get_defaults = function(d,n) + if (d.vi == nil and d.vim == nil) or (d.vi ~= nil and d.vim ~= nil) then + error("option '"..n.."' should have one and only one default value") + end + return get_value(d.vim or d.vi) end local defines = {} @@ -170,11 +171,11 @@ local dump_option = function(i, o) if o.defaults.condition then w(get_cond(o.defaults.condition)) end - w(' .def_val=' .. get_defaults(o.defaults.if_true)) + w(' .def_val=' .. get_defaults(o.defaults.if_true, o.full_name)) if o.defaults.condition then if o.defaults.if_false then w('#else') - w(' .def_val=' .. get_defaults(o.defaults.if_false)) + w(' .def_val=' .. get_defaults(o.defaults.if_false, o.full_name)) end w('#endif') end diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 5c2eed363e..f955fe8859 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -34,6 +34,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/keymap.h" #include "nvim/garray.h" #include "nvim/move.h" @@ -2230,20 +2231,22 @@ static int vgetorpeek(bool advance) timedout = true; continue; } - /* When 'insertmode' is set, ESC just beeps in Insert - * mode. Use CTRL-L to make edit() return. - * For the command line only CTRL-C always breaks it. - * For the cmdline window: Alternate between ESC and - * CTRL-C: ESC for most situations and CTRL-C to close the - * cmdline window. */ - if (p_im && (State & INSERT)) + // When 'insertmode' is set, ESC just beeps in Insert + // mode. Use CTRL-L to make edit() return. + // In Ex-mode \n is compatible with original Vim behaviour. + // For the command line only CTRL-C always breaks it. + // For the cmdline window: Alternate between ESC and + // CTRL-C: ESC for most situations and CTRL-C to close the + // cmdline window. + if (p_im && (State & INSERT)) { c = Ctrl_L; - else if ((State & CMDLINE) - || (cmdwin_type > 0 && tc == ESC) - ) + } else if (exmode_active) { + c = '\n'; + } else if ((State & CMDLINE) || (cmdwin_type > 0 && tc == ESC)) { c = Ctrl_C; - else + } else { c = ESC; + } tc = c; break; } @@ -2413,7 +2416,7 @@ static int vgetorpeek(bool advance) * 1. a scriptfile * 2. the keyboard * - * As much characters as we can get (upto 'maxlen') are put in "buf" and + * As much characters as we can get (up to 'maxlen') are put in "buf" and * NUL terminated (buffer length must be 'maxlen' + 1). * Minimum for "maxlen" is 3!!!! * diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 7c7ce5e65f..96acca4ac7 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -138,14 +138,14 @@ EXTERN int mod_mask INIT(= 0x0); // current key modifiers // update_screen(). EXTERN int cmdline_row; -EXTERN int redraw_cmdline INIT(= false); // cmdline must be redrawn -EXTERN int clear_cmdline INIT(= false); // cmdline must be cleared -EXTERN int mode_displayed INIT(= false); // mode is being displayed -EXTERN int cmdline_star INIT(= false); // cmdline is crypted -EXTERN int redrawing_cmdline INIT(= false); // cmdline is being redrawn -EXTERN int cmdline_was_last_drawn INIT(= false); // cmdline was last drawn +EXTERN bool redraw_cmdline INIT(= false); // cmdline must be redrawn +EXTERN bool clear_cmdline INIT(= false); // cmdline must be cleared +EXTERN bool mode_displayed INIT(= false); // mode is being displayed +EXTERN int cmdline_star INIT(= false); // cmdline is encrypted +EXTERN bool redrawing_cmdline INIT(= false); // cmdline is being redrawn +EXTERN bool cmdline_was_last_drawn INIT(= false); // cmdline was last drawn -EXTERN int exec_from_reg INIT(= false); // executing register +EXTERN bool exec_from_reg INIT(= false); // executing register // When '$' is included in 'cpoptions' option set: // When a change command is given that deletes only part of a line, a dollar @@ -165,7 +165,7 @@ EXTERN int compl_interrupted INIT(= false); // Set when doing something for completion that may call edit() recursively, // which is not allowed. Also used to disable folding during completion -EXTERN int compl_busy INIT(= false); +EXTERN bool compl_busy INIT(= false); // List of flags for method of completion. EXTERN int compl_cont_status INIT(= 0); @@ -201,23 +201,23 @@ EXTERN bool msg_did_scroll INIT(= false); EXTERN char_u *keep_msg INIT(= NULL); // msg to be shown after redraw EXTERN int keep_msg_attr INIT(= 0); // highlight attr for keep_msg -EXTERN int keep_msg_more INIT(= false); // keep_msg was set by msgmore() -EXTERN int need_fileinfo INIT(= false); // do fileinfo() after redraw +EXTERN bool keep_msg_more INIT(= false); // keep_msg was set by msgmore() +EXTERN bool need_fileinfo INIT(= false); // do fileinfo() after redraw EXTERN int msg_scroll INIT(= false); // msg_start() will scroll -EXTERN int msg_didout INIT(= false); // msg_outstr() was used in line -EXTERN int msg_didany INIT(= false); // msg_outstr() was used at all -EXTERN int msg_nowait INIT(= false); // don't wait for this msg +EXTERN bool msg_didout INIT(= false); // msg_outstr() was used in line +EXTERN bool msg_didany INIT(= false); // msg_outstr() was used at all +EXTERN bool msg_nowait INIT(= false); // don't wait for this msg EXTERN int emsg_off INIT(= 0); // don't display errors for now, // unless 'debug' is set. -EXTERN int info_message INIT(= false); // printing informative message +EXTERN bool info_message INIT(= false); // printing informative message EXTERN bool msg_hist_off INIT(= false); // don't add messages to history -EXTERN int need_clr_eos INIT(= false); // need to clear text before +EXTERN bool need_clr_eos INIT(= false); // need to clear text before // displaying a message. EXTERN int emsg_skip INIT(= 0); // don't display errors for // expression that is skipped EXTERN bool emsg_severe INIT(= false); // use message of next of several // emsg() calls for throw -EXTERN int did_endif INIT(= false); // just had ":endif" +EXTERN bool did_endif INIT(= false); // just had ":endif" EXTERN dict_T vimvardict; // Dictionary with v: variables EXTERN dict_T globvardict; // Dictionary with g: variables /// g: value @@ -225,25 +225,24 @@ EXTERN dict_T globvardict; // Dictionary with g: variables EXTERN int did_emsg; // set by emsg() when the message // is displayed or thrown EXTERN bool called_vim_beep; // set if vim_beep() is called -EXTERN int did_emsg_syntax; // did_emsg set because of a +EXTERN bool did_emsg_syntax; // did_emsg set because of a // syntax error EXTERN int called_emsg; // always set by emsg() EXTERN int ex_exitval INIT(= 0); // exit value for ex mode EXTERN bool emsg_on_display INIT(= false); // there is an error message -EXTERN int rc_did_emsg INIT(= false); // vim_regcomp() called emsg() +EXTERN bool rc_did_emsg INIT(= false); // vim_regcomp() called emsg() -EXTERN int no_wait_return INIT(= 0); // don't wait for return for now -EXTERN int need_wait_return INIT(= 0); // need to wait for return later -EXTERN int did_wait_return INIT(= false); // wait_return() was used and - // nothing written since then -EXTERN int need_maketitle INIT(= true); // call maketitle() soon +EXTERN int no_wait_return INIT(= 0); // don't wait for return for now +EXTERN bool need_wait_return INIT(= false); // need to wait for return later +EXTERN bool did_wait_return INIT(= false); // wait_return() was used and + // nothing written since then +EXTERN bool need_maketitle INIT(= true); // call maketitle() soon EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg -EXTERN int ex_keep_indent INIT(= false); // getexmodeline(): keep indent EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0 -EXTERN int didset_vim INIT(= false); // did set $VIM ourselves -EXTERN int didset_vimruntime INIT(= false); // idem for $VIMRUNTIME +EXTERN bool didset_vim INIT(= false); // did set $VIM ourselves +EXTERN bool didset_vimruntime INIT(= false); // idem for $VIMRUNTIME /// Lines left before a "more" message. Ex mode needs to be able to reset this /// after you type something. @@ -369,7 +368,7 @@ EXTERN colnr_T search_match_endcol; // col nr of match end EXTERN linenr_T search_first_line INIT(= 0); // for :{FIRST},{last}s/pat EXTERN linenr_T search_last_line INIT(= MAXLNUM); // for :{first},{LAST}s/pat -EXTERN int no_smartcase INIT(= false); // don't use 'smartcase' once +EXTERN bool no_smartcase INIT(= false); // don't use 'smartcase' once EXTERN int need_check_timestamps INIT(= false); // need to check file // timestamps asap @@ -450,7 +449,7 @@ EXTERN frame_T *topframe; // top of the window frame tree EXTERN tabpage_T *first_tabpage; EXTERN tabpage_T *lastused_tabpage; EXTERN tabpage_T *curtab; -EXTERN int redraw_tabline INIT(= false); // need to redraw tabline +EXTERN bool redraw_tabline INIT(= false); // need to redraw tabline // Iterates over all tabs in the tab list # define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) @@ -502,15 +501,12 @@ EXTERN volatile int full_screen INIT(= false); /// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or /// .vimrc in current directory. -EXTERN int secure INIT(= false); +EXTERN int secure INIT(= 0); /// Non-zero when changing text and jumping to another window/buffer is not /// allowed. EXTERN int textlock INIT(= 0); -/// Non-zero when the current buffer can't be changed. Used for FileChangedRO. -EXTERN int curbuf_lock INIT(= 0); - /// Non-zero when no buffer name can be changed, no buffer can be deleted and /// current directory can't be changed. Used for SwapExists et al. EXTERN int allbuf_lock INIT(= 0); @@ -528,6 +524,8 @@ EXTERN pos_T VIsual; EXTERN int VIsual_active INIT(= false); /// Whether Select mode is active. EXTERN int VIsual_select INIT(= false); +/// Restart Select mode when next cmd finished +EXTERN int restart_VIsual_select INIT(= 0); /// Whether to restart the selection after a Select-mode mapping or menu. EXTERN int VIsual_reselect; /// Type of Visual mode. @@ -559,7 +557,7 @@ EXTERN int end_comment_pending INIT(= NUL); // know that it should not attempt to perform scrollbinding due to the scroll // that was a result of the ":syncbind." (Otherwise, check_scrollbind() will // undo some of the work done by ":syncbind.") -ralston -EXTERN int did_syncbind INIT(= false); +EXTERN bool did_syncbind INIT(= false); // This flag is set when a smart indent has been performed. When the next typed // character is a '{' the inserted tab will be deleted again. @@ -624,8 +622,8 @@ EXTERN long opcount INIT(= 0); // count for pending operator EXTERN int motion_force INIT(=0); // motion force for pending operator // Ex Mode (Q) state -EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM. -EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p. +EXTERN bool exmode_active INIT(= false); // true if Ex mode is active +EXTERN bool ex_no_reprint INIT(=false); // No need to print after z or p. EXTERN int reg_recording INIT(= 0); // register for recording or zero EXTERN int reg_executing INIT(= 0); // register being executed or zero @@ -646,7 +644,7 @@ EXTERN int arrow_used; // Normally false, set to true after EXTERN bool ins_at_eol INIT(= false); // put cursor after eol when // restarting edit after CTRL-O -EXTERN int no_abbr INIT(= true); // true when no abbreviations loaded +EXTERN bool no_abbr INIT(= true); // true when no abbreviations loaded EXTERN int mapped_ctrl_c INIT(= 0); // Modes where CTRL-C is mapped. @@ -666,7 +664,7 @@ EXTERN bool cmd_silent INIT(= false); // don't echo the command line EXTERN int swap_exists_action INIT(= SEA_NONE); // For dialog when swap file already // exists. -EXTERN int swap_exists_did_quit INIT(= false); +EXTERN bool swap_exists_did_quit INIT(= false); // Selected "quit" at the dialog. EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc. @@ -703,14 +701,14 @@ EXTERN bool do_redraw INIT(= false); // extra redraw once EXTERN bool must_redraw_pum INIT(= false); // redraw pum. NB: must_redraw // should also be set. -EXTERN int need_highlight_changed INIT(= true); +EXTERN bool need_highlight_changed INIT(= true); EXTERN FILE *scriptout INIT(= NULL); ///< Stream to write script to. // volatile because it is used in a signal handler. EXTERN volatile int got_int INIT(= false); // set to true when interrupt // signal occurred -EXTERN int bangredo INIT(= false); // set to true with ! command +EXTERN bool bangredo INIT(= false); // set to true with ! command EXTERN int searchcmdlen; // length of previous search cmd EXTERN int reg_do_extmatch INIT(= 0); // Used when compiling regexp: // REX_SET to allow \z\(...\), @@ -720,14 +718,14 @@ EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL); // Set by vim_regexec() to store \z\(...\) matches EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL); -EXTERN int did_outofmem_msg INIT(= false); +EXTERN bool did_outofmem_msg INIT(= false); // set after out of memory msg -EXTERN int did_swapwrite_msg INIT(= false); +EXTERN bool did_swapwrite_msg INIT(= false); // set after swap write error msg EXTERN int global_busy INIT(= 0); // set when :global is executing -EXTERN int listcmd_busy INIT(= false); // set when :argdo, :windo or +EXTERN bool listcmd_busy INIT(= false); // set when :argdo, :windo or // :bufdo is executing -EXTERN int need_start_insertmode INIT(= false); +EXTERN bool need_start_insertmode INIT(= false); // start insert mode soon EXTERN char_u *last_cmdline INIT(= NULL); // last command line (for ":) EXTERN char_u *repeat_cmdline INIT(= NULL); // command line for "." @@ -735,16 +733,16 @@ EXTERN char_u *new_last_cmdline INIT(= NULL); // new value for last_cmdline EXTERN char_u *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline -EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd +EXTERN bool did_cursorhold INIT(= false); // set when CursorHold t'gerd EXTERN int postponed_split INIT(= 0); // for CTRL-W CTRL-] command EXTERN int postponed_split_flags INIT(= 0); // args for win_split() EXTERN int postponed_split_tab INIT(= 0); // cmdmod.tab EXTERN int g_do_tagpreview INIT(= 0); // for tag preview commands: // height of preview window -EXTERN int g_tag_at_cursor INIT(= false); // whether the tag command comes - // from the command line (0) or was - // invoked as a normal command (1) +EXTERN bool g_tag_at_cursor INIT(= false); // whether the tag command comes + // from the command line (0) or was + // invoked as a normal command (1) EXTERN int replace_offset INIT(= 0); // offset for replace_push() @@ -758,7 +756,7 @@ EXTERN int keep_help_flag INIT(= false); // doing :ta from help file // everywhere. EXTERN char_u *empty_option INIT(= (char_u *)""); -EXTERN int redir_off INIT(= false); // no redirection for a moment +EXTERN bool redir_off INIT(= false); // no redirection for a moment EXTERN FILE *redir_fd INIT(= NULL); // message redirection file EXTERN int redir_reg INIT(= 0); // message redirection register EXTERN int redir_vname INIT(= 0); // message redirection variable @@ -792,8 +790,8 @@ extern char_u *compiled_sys; EXTERN char_u *globaldir INIT(= NULL); // Whether 'keymodel' contains "stopsel" and "startsel". -EXTERN int km_stopsel INIT(= false); -EXTERN int km_startsel INIT(= false); +EXTERN bool km_stopsel INIT(= false); +EXTERN bool km_startsel INIT(= false); EXTERN int cedit_key INIT(= -1); ///< key value of 'cedit' option EXTERN int cmdwin_type INIT(= 0); ///< type of cmdline window or 0 diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index 724363674c..dee096214f 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -86,7 +86,7 @@ struct ScreenGrid { int zindex; // Below is state owned by the compositor. Should generally not be set/read - // outside this module, except for specific compatibilty hacks + // outside this module, except for specific compatibility hacks // position of the grid on the composed screen. int comp_row; diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index abba5425e7..1b1735c991 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -1767,7 +1767,7 @@ static bool prt_open_resource(struct prt_ps_resource_S *resource) break; case PRT_DSC_ENDCOMMENTS_TYPE: - // Wont find title or resource after this comment, stop searching + // Won't find title or resource after this comment, stop searching seen_all = true; break; @@ -2398,8 +2398,16 @@ static int prt_add_resource(struct prt_ps_resource_S *resource) EMSG2(_("E456: Can't open file \"%s\""), resource->filename); return FALSE; } - prt_dsc_resources("BeginResource", prt_resource_types[resource->type], - (char *)resource->title); + switch (resource->type) { + case PRT_RESOURCE_TYPE_PROCSET: + case PRT_RESOURCE_TYPE_ENCODING: + case PRT_RESOURCE_TYPE_CMAP: + prt_dsc_resources("BeginResource", prt_resource_types[resource->type], + (char *)resource->title); + break; + default: + return FALSE; + } prt_dsc_textline("BeginDocument", (char *)resource->filename); diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 79e474fa2e..29ee7aae56 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -46,7 +46,7 @@ void highlight_init(void) .id1 = 0, .id2 = 0 })); } -/// @return TRUE if hl table was reset +/// @return true if hl table was reset bool highlight_use_hlstate(void) { if (hlstate_active) { diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 8fa61515ef..a6df0e97e6 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -19,6 +19,7 @@ #include "nvim/misc1.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/search.h" @@ -62,10 +63,10 @@ int get_indent_buf(buf_T *buf, linenr_T lnum) } -// Count the size (in window cells) of the indent in line "ptr", with -// 'tabstop' at "ts". -// If @param list is TRUE, count only screen size for tabs. -int get_indent_str(const char_u *ptr, int ts, int list) +/// Count the size (in window cells) of the indent in line "ptr", with +/// 'tabstop' at "ts". +/// If @param list is true, count only screen size for tabs. +int get_indent_str(const char_u *ptr, int ts, bool list) FUNC_ATTR_NONNULL_ALL { int count = 0; @@ -91,9 +92,9 @@ int get_indent_str(const char_u *ptr, int ts, int list) return count; } -// Count the size (in window cells) of the indent in line "ptr", using -// variable tabstops. -// if "list" is true, count only screen size for tabs. +/// Count the size (in window cells) of the indent in line "ptr", using +/// variable tabstops. +/// if "list" is true, count only screen size for tabs. int get_indent_str_vtab(const char_u *ptr, long ts, long *vts, bool list) { int count = 0; @@ -432,7 +433,7 @@ int get_number_indent(linenr_T lnum) // Return appropriate space number for breakindent, taking influencing // parameters into account. Window must be specified, since it is not // necessarily always the current one. -int get_breakindent_win(win_T *wp, const char_u *line) +int get_breakindent_win(win_T *wp, char_u *line) FUNC_ATTR_NONNULL_ALL { static int prev_indent = 0; // Cached indent value. @@ -462,12 +463,32 @@ int get_breakindent_win(win_T *wp, const char_u *line) } bri = prev_indent + wp->w_briopt_shift; + // Add offset for number column, if 'n' is in 'cpoptions' + bri += win_col_off2(wp); + + // add additional indent for numbered lists + if (wp->w_briopt_list != 0) { + regmatch_T regmatch = { + .regprog = vim_regcomp(curbuf->b_p_flp, + RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT), + }; + + if (regmatch.regprog != NULL) { + if (vim_regexec(®match, line, 0)) { + if (wp->w_briopt_list > 0) { + bri += wp->w_briopt_list; + } else { + bri = (int)(*regmatch.endp - *regmatch.startp); + } + } + vim_regfree(regmatch.regprog); + } + } + // indent minus the length of the showbreak string if (wp->w_briopt_sbr) { - bri -= vim_strsize(p_sbr); + bri -= vim_strsize(get_showbreak_value(wp)); } - // Add offset for number column, if 'n' is in 'cpoptions' - bri += win_col_off2(wp); // never indent past left window margin if (bri < 0) { diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 6dacace0a4..277b9ade89 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -543,7 +543,7 @@ unsigned int trans_special(const char_u **srcp, const size_t src_len, /// Put the character sequence for "key" with "modifiers" into "dst" and return /// the resulting length. -/// When "keycode" is TRUE prefer key code, e.g. K_DEL instead of DEL. +/// When "keycode" is true prefer key code, e.g. K_DEL instead of DEL. /// The sequence is not NUL terminated. /// This is how characters in a string are encoded. unsigned int special_to_buf(int key, int modifiers, bool keycode, char_u *dst) diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h index d31196d412..9fc44f6f84 100644 --- a/src/nvim/keymap.h +++ b/src/nvim/keymap.h @@ -9,11 +9,11 @@ * Any special key code sequences are replaced by these codes. */ -/* - * For MSDOS some keys produce codes larger than 0xff. They are split into two - * chars, the first one is K_NUL. - */ -#define K_NUL (0xce) // for MSDOS: special key follows +// +// For MS-DOS some keys produce codes larger than 0xff. They are split into two +// chars, the first one is K_NUL. +// +#define K_NUL (0xce) // for MS-DOS: special key follows /* * K_SPECIAL is the first byte of a special key code and is always followed by diff --git a/src/nvim/log.h b/src/nvim/log.h index 17d754c033..654b682de8 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -7,7 +7,7 @@ #include "auto/config.h" #include "nvim/macros.h" -// USDT probes. Example invokation: +// USDT probes. Example invocation: // NVIM_PROBE(nvim_foo_bar, 1, string.data); #if defined(HAVE_SYS_SDT_H) #include <sys/sdt.h> // NOLINT diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 4d4286354b..5799c3ee98 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -45,6 +45,9 @@ static int in_fast_callback = 0; +// Initialized in nlua_init(). +static lua_State *global_lstate = NULL; + typedef struct { Error err; String lua_err_str; @@ -144,12 +147,12 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 1; } -/// convert byte index to UTF-32 and UTF-16 indicies +/// convert byte index to UTF-32 and UTF-16 indices /// /// Expects a string and an optional index. If no index is supplied, the length /// of the string is returned. /// -/// Returns two values: the UTF-32 and UTF-16 indicies. +/// Returns two values: the UTF-32 and UTF-16 indices. static int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL { size_t s1_len; @@ -173,7 +176,7 @@ static int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 2; } -/// convert UTF-32 or UTF-16 indicies to byte index. +/// convert UTF-32 or UTF-16 indices to byte index. /// /// Expects up to three args: string, index and use_utf16. /// If use_utf16 is not supplied it defaults to false (use UTF-32) @@ -234,7 +237,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, multiqueue_put(main_loop.events, nlua_luv_error_event, 1, xstrdup(error)); - lua_pop(lstate, 1); // error mesage + lua_pop(lstate, 1); // error message retval = -status; } else { // LUA_OK if (nresult == LUA_MULTRET) { @@ -250,7 +253,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, static void nlua_schedule_event(void **argv) { LuaRef cb = (LuaRef)(ptrdiff_t)argv[0]; - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; nlua_pushref(lstate, cb); nlua_unref(lstate, cb); if (lua_pcall(lstate, 0, 0, 0)) { @@ -553,14 +556,10 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 0; } -/// Initialize lua interpreter +/// Initialize global lua interpreter /// -/// Crashes Nvim if initialization fails. Should be called once per lua -/// interpreter instance. -/// -/// @return New lua interpreter instance. -static lua_State *nlua_init(void) - FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT +/// Crashes Nvim if initialization fails. +void nlua_init(void) { #ifdef NLUA_TRACK_REFS const char *env = os_getenv("NVIM_LUA_NOTRACK"); @@ -577,28 +576,9 @@ static lua_State *nlua_init(void) luaL_openlibs(lstate); nlua_state_init(lstate); - return lstate; + global_lstate = lstate; } -// only to be used by nlua_enter and nlua_free_all_mem! -static lua_State *global_lstate = NULL; - -/// Enter lua interpreter -/// -/// Calls nlua_init() if needed. Is responsible for pre-lua call initalization -/// like updating `package.[c]path` with directories derived from &runtimepath. -/// -/// @return Interpreter instance to use. Will either be initialized now or -/// taken from previous initialization. -static lua_State *nlua_enter(void) - FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT -{ - if (global_lstate == NULL) { - global_lstate = nlua_init(); - } - lua_State *const lstate = global_lstate; - return lstate; -} void nlua_free_all_mem(void) { @@ -1043,8 +1023,7 @@ void nlua_unref(lua_State *lstate, LuaRef ref) void api_free_luaref(LuaRef ref) { - lua_State *const lstate = nlua_enter(); - nlua_unref(lstate, ref); + nlua_unref(global_lstate, ref); } /// push a value referenced in the registry @@ -1064,7 +1043,7 @@ LuaRef api_new_luaref(LuaRef original_ref) return LUA_NOREF; } - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; nlua_pushref(lstate, original_ref); LuaRef new_ref = nlua_ref(lstate, -1); lua_pop(lstate, 1); @@ -1143,7 +1122,7 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, return; } - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; if (luaL_loadbuffer(lstate, lcmd, lcmd_len, name)) { nlua_error(lstate, _("E5107: Error loading lua %.*s")); return; @@ -1233,7 +1212,7 @@ int typval_exec_lua_callable( /// @return Return value of the execution. Object nlua_exec(const String str, const Array args, Error *err) { - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) { size_t len; @@ -1270,7 +1249,7 @@ Object nlua_exec(const String str, const Array args, Error *err) Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Error *err) { - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; nlua_pushref(lstate, ref); int nargs = (int)args.size; if (name != NULL) { @@ -1346,7 +1325,7 @@ void ex_luado(exarg_T *const eap) const char *const cmd = (const char *)eap->arg; const size_t cmd_len = strlen(cmd); - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; #define DOSTART "return function(line, linenr) " #define DOEND " end" @@ -1431,7 +1410,7 @@ void ex_luafile(exarg_T *const eap) bool nlua_exec_file(const char *path) FUNC_ATTR_NONNULL_ALL { - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; if (luaL_loadfile(lstate, path)) { nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s")); @@ -1480,7 +1459,7 @@ int nlua_expand_pat(expand_T *xp, int *num_results, char_u ***results) { - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; int ret = OK; // [ vim ] @@ -1690,7 +1669,7 @@ int nlua_CFunction_func_call( typval_T *rettv, void *state) { - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; LuaCFunctionState *funcstate = (LuaCFunctionState *)state; return typval_exec_lua_callable(lstate, funcstate->lua_callable, @@ -1699,7 +1678,7 @@ int nlua_CFunction_func_call( void nlua_CFunction_func_free(void *state) { - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; LuaCFunctionState *funcstate = (LuaCFunctionState *)state; nlua_unref(lstate, funcstate->lua_callable.func_ref); @@ -1730,7 +1709,7 @@ char_u *nlua_register_table_as_callable(typval_T *const arg) return NULL; } - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; #ifndef NDEBUG int top = lua_gettop(lstate); @@ -1769,7 +1748,7 @@ void nlua_execute_log_keystroke(int c) char_u buf[NUMBUFLEN]; size_t buf_len = special_to_buf(c, mod_mask, false, buf); - lua_State *const lstate = nlua_enter(); + lua_State *const lstate = global_lstate; #ifndef NDEBUG int top = lua_gettop(lstate); diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index e3fa48f530..1425baacf0 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -384,7 +384,7 @@ static int parser_parse(lua_State *L) // Sometimes parsing fails (timeout, or wrong parser ABI) // In those case, just return an error. if (!new_tree) { - return luaL_error(L, "An error occured when parsing."); + return luaL_error(L, "An error occurred when parsing."); } // The new tree will be pushed to the stack, without copy, owwership is now to diff --git a/src/nvim/macros.h b/src/nvim/macros.h index e718254fb9..e1aa1b7704 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -34,10 +34,6 @@ /// LINEEMPTY() - return TRUE if the line is empty #define LINEEMPTY(p) (*ml_get(p) == NUL) -/// BUFEMPTY() - return TRUE if the current buffer is empty -#define BUFEMPTY() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == \ - NUL) - // toupper() and tolower() that use the current locale. // Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the // range 0 - 255. toupper()/tolower() on some systems can't handle others. @@ -133,6 +129,8 @@ /// error. A mechanism to detect many (though not all) of those errors at /// compile time is implemented. It works by the second division producing /// a division by zero in those cases (-Wdiv-by-zero in GCC). +/// +/// -V:ARRAY_SIZE:1063 #define ARRAY_SIZE(arr) \ ((sizeof(arr)/sizeof((arr)[0])) \ / ((size_t)(!(sizeof(arr) % sizeof((arr)[0]))))) diff --git a/src/nvim/main.c b/src/nvim/main.c index 7d7eba2105..252aa81825 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -7,8 +7,6 @@ #include <string.h> #include <stdbool.h> -#include <lua.h> -#include <lauxlib.h> #include <msgpack.h> #include "nvim/ascii.h" @@ -258,6 +256,8 @@ int main(int argc, char **argv) // Check if we have an interactive window. check_and_set_isatty(¶ms); + nlua_init(); + // Process the command line arguments. File names are put in the global // argument list "global_alist". command_line_scan(¶ms); @@ -318,7 +318,8 @@ int main(int argc, char **argv) debug_break_level = params.use_debug_break_level; // Read ex-commands if invoked with "-es". - if (!params.input_isatty && silent_mode && exmode_active == EXMODE_NORMAL) { + if (!params.input_isatty && !params.input_neverscript + && silent_mode && exmode_active) { input_start(STDIN_FILENO); } @@ -341,7 +342,6 @@ int main(int argc, char **argv) TIME_MSG("initialized screen early for UI"); } - // open terminals when opening files that start with term:// #define PROTO "term://" do_cmdline_cmd("augroup nvim_terminal"); @@ -765,7 +765,7 @@ static bool edit_stdin(bool explicit, mparm_T *parmp) { bool implicit = !headless_mode && !embedded_mode - && exmode_active != EXMODE_NORMAL // -E/-Es but not -e/-es. + && (!exmode_active || parmp->input_neverscript) && !parmp->input_isatty && scriptin[0] == NULL; // `-s -` was not given. return explicit || implicit; @@ -908,11 +908,12 @@ static void command_line_scan(mparm_T *parmp) break; } case 'e': { // "-e" Ex mode - exmode_active = EXMODE_NORMAL; + exmode_active = true; break; } case 'E': { // "-E" Ex mode - exmode_active = EXMODE_VIM; + exmode_active = true; + parmp->input_neverscript = true; break; } case 'f': { // "-f" GUI: run in foreground. @@ -1424,7 +1425,7 @@ static void handle_quickfix(mparm_T *paramp) static void handle_tag(char_u *tagname) { if (tagname != NULL) { - swap_exists_did_quit = FALSE; + swap_exists_did_quit = false; vim_snprintf((char *)IObuff, IOSIZE, "ta %s", tagname); do_cmdline_cmd((char *)IObuff); @@ -1442,13 +1443,11 @@ static void read_stdin(void) // When getting the ATTENTION prompt here, use a dialog. swap_exists_action = SEA_DIALOG; no_wait_return = true; - int save_msg_didany = msg_didany; + bool save_msg_didany = msg_didany; set_buflisted(true); - // Create memfile and read from stdin. (void)open_buffer(true, NULL, 0); - - if (BUFEMPTY() && curbuf->b_next != NULL) { + if (buf_is_empty(curbuf) && curbuf->b_next != NULL) { // stdin was empty, go to buffer 2 (e.g. "echo file1 | xargs nvim"). #8561 do_cmdline_cmd("silent! bnext"); // Delete the empty stdin buffer. @@ -1634,7 +1633,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) curwin->w_arg_idx = arg_idx; /* Edit file from arg list, if there is one. When "Quit" selected * at the ATTENTION prompt close the window. */ - swap_exists_did_quit = FALSE; + swap_exists_did_quit = false; (void)do_ecmd(0, arg_idx < GARGCOUNT ? alist_name(&GARGLIST[arg_idx]) : NULL, NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin); @@ -1816,7 +1815,8 @@ static bool do_user_initialization(void) char_u *vimrc_path = (char_u *)stdpaths_user_conf_subpath("init.vim"); if (os_path_exists(vimrc_path)) { - EMSG3(_("Conflicting configs: \"%s\" \"%s\""), init_lua_path, vimrc_path); + EMSG3(_("E5422: Conflicting configs: \"%s\" \"%s\""), init_lua_path, + vimrc_path); } xfree(vimrc_path); @@ -2000,10 +2000,10 @@ static void mainerr(const char *errstr, const char *str) /// Prints version information for "nvim -v" or "nvim --version". static void version(void) { - info_message = TRUE; // use mch_msg(), not mch_errmsg() + info_message = true; // use mch_msg(), not mch_errmsg() list_version(); msg_putchar('\n'); - msg_didout = FALSE; + msg_didout = false; } /// Prints help message for "nvim -h" or "nvim --help". diff --git a/src/nvim/main.h b/src/nvim/main.h index 61252f2bce..d387e6d668 100644 --- a/src/nvim/main.h +++ b/src/nvim/main.h @@ -30,6 +30,7 @@ typedef struct { bool input_isatty; // stdin is a terminal bool output_isatty; // stdout is a terminal bool err_isatty; // stderr is a terminal + bool input_neverscript; // never treat stdin as script (-E/-Es) int no_swap_file; // "-n" argument used int use_debug_break_level; int window_count; // number of windows to use diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 73a9c1d1d7..0b14089550 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -108,7 +108,7 @@ int setmark_pos(int c, pos_T *pos, int fnum) return OK; } - // Can't set a mark in a non-existant buffer. + // Can't set a mark in a non-existent buffer. buf_T *buf = buflist_findnr(fnum); if (buf == NULL) { return FAIL; @@ -346,10 +346,10 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum) } else if (c == '{' || c == '}') { // to previous/next paragraph pos_T pos; oparg_T oa; - int slcb = listcmd_busy; + bool slcb = listcmd_busy; pos = curwin->w_cursor; - listcmd_busy = TRUE; /* avoid that '' is changed */ + listcmd_busy = true; // avoid that '' is changed if (findpar(&oa.inclusive, c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) { pos_copy = curwin->w_cursor; @@ -359,10 +359,10 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum) listcmd_busy = slcb; } else if (c == '(' || c == ')') { /* to previous/next sentence */ pos_T pos; - int slcb = listcmd_busy; + bool slcb = listcmd_busy; pos = curwin->w_cursor; - listcmd_busy = TRUE; /* avoid that '' is changed */ + listcmd_busy = true; // avoid that '' is changed if (findsent(c == ')' ? FORWARD : BACKWARD, 1L)) { pos_copy = curwin->w_cursor; posp = &pos_copy; diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index feb54eae4a..d0d843cbf8 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -905,6 +905,7 @@ continue_same_node: refkey(b, enditr->node, enditr->i); } else { past_right = true; // NOLINT + (void)past_right; break; } } diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h index 8a1c564a6d..3b83e3c44d 100644 --- a/src/nvim/marktree.h +++ b/src/nvim/marktree.h @@ -49,7 +49,7 @@ struct mtnode_s { int32_t n; int32_t level; // TODO(bfredl): we could consider having a only-sometimes-valid - // index into parent for faster "chached" lookup. + // index into parent for faster "cached" lookup. mtnode_t *parent; mtkey_t key[2 * MT_BRANCH_FACTOR - 1]; mtnode_t *ptr[]; diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 73e3ba53a5..cba372b9d3 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -73,9 +73,6 @@ struct interval { # include "unicode_tables.generated.h" #endif -char_u e_loadlib[] = "E370: Could not load library %s"; -char_u e_loadfunc[] = "E448: Could not load library function %s"; - // To speed up BYTELEN(); keep a lookup table to quickly get the length in // bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes // which are illegal when used as the first byte have a 1. The NUL byte has @@ -2354,10 +2351,8 @@ int convert_setup(vimconv_T *vcp, char_u *from, char_u *to) return convert_setup_ext(vcp, from, true, to, true); } -/* - * As convert_setup(), but only when from_unicode_is_utf8 is TRUE will all - * "from" unicode charsets be considered utf-8. Same for "to". - */ +/// As convert_setup(), but only when from_unicode_is_utf8 is true will all +/// "from" unicode charsets be considered utf-8. Same for "to". int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, char_u *to, bool to_unicode_is_utf8) { diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h index 2402d2147d..3eaa7d83e0 100644 --- a/src/nvim/memfile_defs.h +++ b/src/nvim/memfile_defs.h @@ -101,7 +101,7 @@ typedef struct memfile { blocknr_T mf_neg_count; /// number of negative blocks numbers blocknr_T mf_infile_count; /// number of pages in the file unsigned mf_page_size; /// number of bytes in a page - bool mf_dirty; /// TRUE if there are dirty blocks + bool mf_dirty; /// true if there are dirty blocks } memfile_T; #endif // NVIM_MEMFILE_DEFS_H diff --git a/src/nvim/memline.c b/src/nvim/memline.c index cb2437b2b3..8229b8f6bc 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -118,15 +118,15 @@ struct pointer_block { * etc. Thus the order of the lines is the opposite of the line number. */ struct data_block { - uint16_t db_id; /* ID for data block: DATA_ID */ - unsigned db_free; /* free space available */ - unsigned db_txt_start; /* byte where text starts */ - unsigned db_txt_end; /* byte just after data block */ - linenr_T db_line_count; /* number of lines in this block */ - unsigned db_index[1]; /* index for start of line (actually bigger) - * followed by empty space upto db_txt_start - * followed by the text in the lines until - * end of page */ + uint16_t db_id; // ID for data block: DATA_ID + unsigned db_free; // free space available + unsigned db_txt_start; // byte where text starts + unsigned db_txt_end; // byte just after data block + linenr_T db_line_count; // number of lines in this block + unsigned db_index[1]; // index for start of line (actually bigger) + // followed by empty space up to db_txt_start + // followed by the text in the lines until + // end of page }; /* @@ -3575,9 +3575,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, } } else { MSG_PUTS("\n"); - if (msg_silent == 0) - /* call wait_return() later */ - need_wait_return = TRUE; + if (msg_silent == 0) { + // call wait_return() later + need_wait_return = true; + } } } diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 112f51fc64..5c07f87bd5 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -955,7 +955,7 @@ char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg, after_dot = p + 1; } - // ":popup" only uses menues, not entries + // ":popup" only uses menus, not entries expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p'); expand_emenu = (*cmd == 'e'); if (expand_menus && ascii_iswhite(*p)) { diff --git a/src/nvim/message.c b/src/nvim/message.c index ec5dabbbc0..bd26b8608f 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -79,12 +79,12 @@ static int verbose_did_open = FALSE; /* * When writing messages to the screen, there are many different situations. * A number of variables is used to remember the current state: - * msg_didany TRUE when messages were written since the last time the + * msg_didany true when messages were written since the last time the * user reacted to a prompt. * Reset: After hitting a key for the hit-return prompt, * hitting <CR> for the command line or input(). * Set: When any message is written to the screen. - * msg_didout TRUE when something was written to the current line. + * msg_didout true when something was written to the current line. * Reset: When advancing to the next line, when the current * text can be overwritten. * Set: When any message is written to the screen. @@ -102,7 +102,7 @@ static int verbose_did_open = FALSE; * work without an extra prompt. * lines_left Number of lines available for messages before the * more-prompt is to be given. -1 when not set. - * need_wait_return TRUE when the hit-return prompt is needed. + * need_wait_return true when the hit-return prompt is needed. * Reset: After giving the hit-return prompt, when the user * has answered some other prompt. * Set: When the ruler or typeahead display is overwritten, @@ -1097,14 +1097,14 @@ void wait_return(int redraw) */ if (vgetc_busy > 0) return; - need_wait_return = TRUE; + need_wait_return = true; if (no_wait_return) { if (!exmode_active) cmdline_row = msg_row; return; } - redir_off = TRUE; /* don't redirect this message */ + redir_off = true; // don't redirect this message oldState = State; if (quit_more) { c = CAR; /* just pretend CR was hit */ @@ -1165,11 +1165,11 @@ void wait_return(int redraw) if (p_more) { if (c == 'b' || c == 'k' || c == 'u' || c == 'g' || c == K_UP || c == K_PAGEUP) { - if (msg_scrolled > Rows) - /* scroll back to show older messages */ + if (msg_scrolled > Rows) { + // scroll back to show older messages do_more_prompt(c); - else { - msg_didout = FALSE; + } else { + msg_didout = false; c = K_IGNORE; msg_col = cmdmsg_rl ? Columns - 1 : @@ -1284,7 +1284,7 @@ void set_keep_msg(char_u *s, int attr) keep_msg = vim_strsave(s); else keep_msg = NULL; - keep_msg_more = FALSE; + keep_msg_more = false; keep_msg_attr = attr; } @@ -1324,9 +1324,8 @@ void msg_start(void) 0; } else if (msg_didout) { // start message on next line msg_putchar('\n'); - did_return = TRUE; - if (exmode_active != EXMODE_NORMAL) - cmdline_row = msg_row; + did_return = true; + cmdline_row = msg_row; } if (!msg_didany || lines_left < 0) msg_starthere(); @@ -1354,7 +1353,7 @@ void msg_start(void) void msg_starthere(void) { lines_left = cmdline_row; - msg_didany = FALSE; + msg_didany = false; } void msg_putchar(int c) @@ -2146,15 +2145,17 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true); } - if (*s == '\n') { /* go to next line */ - msg_didout = FALSE; /* remember that line is empty */ - if (cmdmsg_rl) + if (*s == '\n') { // go to next line + msg_didout = false; // remember that line is empty + if (cmdmsg_rl) { msg_col = Columns - 1; - else + } else { msg_col = 0; - if (++msg_row >= Rows) /* safety check */ + } + if (++msg_row >= Rows) { // safety check msg_row = Rows - 1; - } else if (*s == '\r') { /* go to column 0 */ + } + } else if (*s == '\r') { // go to column 0 msg_col = 0; } else if (*s == '\b') { /* go to previous char */ if (msg_col) @@ -2709,9 +2710,9 @@ static int do_more_prompt(int typed_char) /* Since got_int is set all typeahead will be flushed, but we * want to keep this ':', remember that in a special way. */ typeahead_noflush(':'); - cmdline_row = Rows - 1; /* put ':' on this line */ - skip_redraw = TRUE; /* skip redraw once */ - need_wait_return = FALSE; /* don't wait in main() */ + cmdline_row = Rows - 1; // put ':' on this line + skip_redraw = true; // skip redraw once + need_wait_return = false; // don't wait in main() } FALLTHROUGH; case 'q': // quit @@ -2932,7 +2933,7 @@ void repeat_message(void) /* Avoid drawing the "hit-enter" prompt below the previous one, * overwrite it. Esp. useful when regaining focus and a * FocusGained autocmd exists but didn't draw anything. */ - msg_didout = FALSE; + msg_didout = false; msg_col = 0; msg_clr_eos(); } @@ -3096,8 +3097,8 @@ void msg_check(void) return; } if (msg_row == Rows - 1 && msg_col >= sc_col) { - need_wait_return = TRUE; - redraw_cmdline = TRUE; + need_wait_return = true; + redraw_cmdline = true; } } diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 38d0a7dadf..6d94632687 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -349,178 +349,6 @@ int get_last_leader_offset(char_u *line, char_u **flags) return result; } -/* - * Return the number of window lines occupied by buffer line "lnum". - */ -int plines(const linenr_T lnum) -{ - return plines_win(curwin, lnum, true); -} - -int plines_win( - win_T *const wp, - const linenr_T lnum, - const bool winheight // when true limit to window height -) -{ - /* Check for filler lines above this buffer line. When folded the result - * is one line anyway. */ - return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum); -} - -int plines_nofill(const linenr_T lnum) -{ - return plines_win_nofill(curwin, lnum, true); -} - -int plines_win_nofill( - win_T *const wp, - const linenr_T lnum, - const bool winheight // when true limit to window height -) -{ - if (!wp->w_p_wrap) { - return 1; - } - - if (wp->w_width_inner == 0) { - return 1; - } - - // A folded lines is handled just like an empty line. - if (lineFolded(wp, lnum)) { - return 1; - } - - const int lines = plines_win_nofold(wp, lnum); - if (winheight && lines > wp->w_height_inner) { - return wp->w_height_inner; - } - return lines; -} - -/* - * Return number of window lines physical line "lnum" will occupy in window - * "wp". Does not care about folding, 'wrap' or 'diff'. - */ -int plines_win_nofold(win_T *wp, linenr_T lnum) -{ - char_u *s; - unsigned int col; - int width; - - s = ml_get_buf(wp->w_buffer, lnum, FALSE); - if (*s == NUL) /* empty line */ - return 1; - col = win_linetabsize(wp, s, MAXCOL); - - // If list mode is on, then the '$' at the end of the line may take up one - // extra column. - if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) { - col += 1; - } - - /* - * Add column offset for 'number', 'relativenumber' and 'foldcolumn'. - */ - width = wp->w_width_inner - win_col_off(wp); - if (width <= 0 || col > 32000) { - return 32000; // bigger than the number of screen columns - } - if (col <= (unsigned int)width) { - return 1; - } - col -= (unsigned int)width; - width += win_col_off2(wp); - assert(col <= INT_MAX && (int)col < INT_MAX - (width -1)); - return ((int)col + (width - 1)) / width + 1; -} - -/* - * Like plines_win(), but only reports the number of physical screen lines - * used from the start of the line to the given column number. - */ -int plines_win_col(win_T *wp, linenr_T lnum, long column) -{ - // Check for filler lines above this buffer line. When folded the result - // is one line anyway. - int lines = diff_check_fill(wp, lnum); - - if (!wp->w_p_wrap) - return lines + 1; - - if (wp->w_width_inner == 0) { - return lines + 1; - } - - char_u *line = ml_get_buf(wp->w_buffer, lnum, false); - char_u *s = line; - - colnr_T col = 0; - while (*s != NUL && --column >= 0) { - col += win_lbr_chartabsize(wp, line, s, col, NULL); - MB_PTR_ADV(s); - } - - // If *s is a TAB, and the TAB is not displayed as ^I, and we're not in - // INSERT mode, then col must be adjusted so that it represents the last - // screen position of the TAB. This only fixes an error when the TAB wraps - // from one screen line to the next (when 'columns' is not a multiple of - // 'ts') -- webb. - if (*s == TAB && (State & NORMAL) - && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { - col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1; - } - - // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. - int width = wp->w_width_inner - win_col_off(wp); - if (width <= 0) { - return 9999; - } - - lines += 1; - if (col > width) - lines += (col - width) / (width + win_col_off2(wp)) + 1; - return lines; -} - -/// Get the number of screen lines lnum takes up. This takes care of -/// both folds and topfill, and limits to the current window height. -/// -/// @param[in] wp window line is in -/// @param[in] lnum line number -/// @param[out] nextp if not NULL, the line after a fold -/// @param[out] foldedp if not NULL, whether lnum is on a fold -/// @param[in] cache whether to use the window's cache for folds -/// -/// @return the total number of screen lines -int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, - bool *const foldedp, const bool cache) -{ - bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL); - if (foldedp) { - *foldedp = folded; - } - if (folded) { - return 1; - } else if (lnum == wp->w_topline) { - return plines_win_nofill(wp, lnum, true) + wp->w_topfill; - } - return plines_win(wp, lnum, true); -} - -int plines_m_win(win_T *wp, linenr_T first, linenr_T last) -{ - int count = 0; - - while (first <= last) { - linenr_T next = first; - count += plines_win_full(wp, first, &next, NULL, false); - first = next + 1; - } - return count; -} - int gchar_pos(pos_T *pos) FUNC_ATTR_NONNULL_ARG(1) { @@ -750,8 +578,8 @@ get_number ( stuffcharReadbuff(':'); if (!exmode_active) cmdline_row = msg_row; - skip_redraw = TRUE; /* skip redraw once */ - do_redraw = FALSE; + skip_redraw = true; // skip redraw once + do_redraw = false; break; } else if (c == Ctrl_C || c == ESC || c == 'q') { n = 0; @@ -849,7 +677,7 @@ void msgmore(long n) } if (msg(msg_buf)) { set_keep_msg(msg_buf, 0); - keep_msg_more = TRUE; + keep_msg_more = true; } } } diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 4c0339e5f4..6c25525936 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -18,6 +18,7 @@ #include "nvim/diff.h" #include "nvim/move.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/cursor.h" #include "nvim/buffer_defs.h" #include "nvim/memline.h" @@ -236,12 +237,14 @@ retnomove: if (row < 0) { count = 0; for (first = true; curwin->w_topline > 1; ) { - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) - ++count; - else - count += plines(curwin->w_topline - 1); - if (!first && count > -row) + if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { + count++; + } else { + count += plines_win(curwin, curwin->w_topline - 1, true); + } + if (!first && count > -row) { break; + } first = false; (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { @@ -262,7 +265,7 @@ retnomove: if (curwin->w_topfill > 0) { ++count; } else { - count += plines(curwin->w_topline); + count += plines_win(curwin, curwin->w_topline, true); } if (!first && count > row - curwin->w_height_inner + 1) { @@ -522,7 +525,7 @@ static colnr_T scroll_line_len(linenr_T lnum) char_u *line = ml_get(lnum); if (*line != NUL) { for (;;) { - int numchar = chartabsize(line, col); + int numchar = win_chartabsize(curwin, line, col); MB_PTR_ADV(line); if (*line == NUL) { // don't count the last character break; @@ -570,9 +573,8 @@ static linenr_T find_longest_lnum(void) return ret; } -/// -/// Do a horizontal scroll. Return TRUE if the cursor moved, FALSE otherwise. -/// +/// Do a horizontal scroll. +/// @return true if the cursor moved, false otherwise. bool mouse_scroll_horiz(int dir) { if (curwin->w_p_wrap) { @@ -619,10 +621,10 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // scanned *up to* `col`, nudging it left or right when concealed characters // are encountered. // - // chartabsize() is used to keep track of the virtual column position relative - // to the line's bytes. For example: if col == 9 and the line starts with a - // tab that's 8 columns wide, we would want the cursor to be highlighting the - // second byte, not the ninth. + // win_chartabsize() is used to keep track of the virtual column position + // relative to the line's bytes. For example: if col == 9 and the line + // starts with a tab that's 8 columns wide, we would want the cursor to be + // highlighting the second byte, not the ninth. linenr_T lnum = wp->w_cursor.lnum; char_u *line = ml_get(lnum); @@ -646,7 +648,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // checked for concealed characters. vcol = 0; while (vcol < offset && *ptr != NUL) { - vcol += chartabsize(ptr, vcol); + vcol += win_chartabsize(curwin, ptr, vcol); ptr += utfc_ptr2len(ptr); } @@ -657,7 +659,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; ptr_end = ptr_row_offset; while (vcol < col && *ptr_end != NUL) { - vcol += chartabsize(ptr_end, vcol); + vcol += win_chartabsize(curwin, ptr_end, vcol); ptr_end += utfc_ptr2len(ptr_end); } @@ -672,7 +674,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) #define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { - cwidth = chartabsize(ptr, vcol); + cwidth = win_chartabsize(curwin, ptr, vcol); vcol += cwidth; if (cwidth > 1 && *ptr == '\t' && nudge > 0) { // A tab will "absorb" any previous adjustments. diff --git a/src/nvim/move.c b/src/nvim/move.c index 1210a3365a..09815d1e6a 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -17,6 +17,7 @@ #include <stdbool.h> #include "nvim/ascii.h" +#include "nvim/buffer.h" #include "nvim/move.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -26,6 +27,7 @@ #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/option.h" #include "nvim/popupmnu.h" #include "nvim/screen.h" @@ -172,7 +174,7 @@ void update_topline(win_T *wp) old_topfill = wp->w_topfill; // If the buffer is empty, always set topline to 1. - if (BUFEMPTY()) { // special case - file is empty + if (buf_is_empty(curbuf)) { // special case - file is empty if (wp->w_topline != 1) { redraw_later(wp, NOT_VALID); } @@ -1054,8 +1056,9 @@ bool scrolldown(long line_count, int byfold) line_count -= curwin->w_topline - first - 1; curwin->w_botline -= curwin->w_topline - first; curwin->w_topline = first; - } else - done += plines_nofill(curwin->w_topline); + } else { + done += plines_win_nofill(curwin, curwin->w_topline, true); + } } --curwin->w_botline; /* approximate w_botline */ invalidate_botline(); @@ -1089,8 +1092,9 @@ bool scrolldown(long line_count, int byfold) curwin->w_cursor.lnum = 1; else curwin->w_cursor.lnum = first - 1; - } else - wrow -= plines(curwin->w_cursor.lnum--); + } else { + wrow -= plines_win(curwin, curwin->w_cursor.lnum--, true); + } curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL); moved = true; @@ -1193,7 +1197,7 @@ check_topfill ( */ static void max_topfill(void) { - int n = plines_nofill(curwin->w_topline); + int n = plines_win_nofill(curwin, curwin->w_topline, true); if (n >= curwin->w_height_inner) { curwin->w_topfill = 0; } else { @@ -1220,19 +1224,16 @@ void scrolldown_clamp(void) validate_cursor(); /* w_wrow needs to be valid */ - /* - * Compute the row number of the last row of the cursor line - * and make sure it doesn't go off the screen. Make sure the cursor - * doesn't go past 'scrolloff' lines from the screen end. - */ + // Compute the row number of the last row of the cursor line + // and make sure it doesn't go off the screen. Make sure the cursor + // doesn't go past 'scrolloff' lines from the screen end. int end_row = curwin->w_wrow; - if (can_fill) - ++end_row; - else - end_row += plines_nofill(curwin->w_topline - 1); - if (curwin->w_p_wrap - && curwin->w_width_inner != 0 - ) { + if (can_fill) { + end_row++; + } else { + end_row += plines_win_nofill(curwin, curwin->w_topline - 1, true); + } + if (curwin->w_p_wrap && curwin->w_width_inner != 0) { validate_cheight(); validate_virtcol(); end_row += curwin->w_cline_height - 1 - @@ -1265,16 +1266,13 @@ void scrollup_clamp(void) validate_cursor(); /* w_wrow needs to be valid */ - /* - * Compute the row number of the first row of the cursor line - * and make sure it doesn't go off the screen. Make sure the cursor - * doesn't go before 'scrolloff' lines from the screen start. - */ - int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline) - - curwin->w_topfill; - if (curwin->w_p_wrap - && curwin->w_width_inner != 0 - ) { + // Compute the row number of the first row of the cursor line + // and make sure it doesn't go off the screen. Make sure the cursor + // doesn't go before 'scrolloff' lines from the screen start. + int start_row = (curwin->w_wrow + - plines_win_nofill(curwin, curwin->w_topline, true) + - curwin->w_topfill); + if (curwin->w_p_wrap && curwin->w_width_inner != 0) { validate_virtcol(); start_row -= curwin->w_virtcol / curwin->w_width_inner; } @@ -1421,14 +1419,15 @@ void scroll_cursor_top(int min_scroll, int always) while (top > 0) { int i = hasFolding(top, &top, NULL) ? 1 // count one logical line for a sequence of folded lines - : plines_nofill(top); + : plines_win_nofill(curwin, top, true); used += i; if (extra + i <= off && bot < curbuf->b_ml.ml_line_count) { - if (hasFolding(bot, NULL, &bot)) - /* count one logical line for a sequence of folded lines */ - ++used; - else - used += plines(bot); + if (hasFolding(bot, NULL, &bot)) { + // count one logical line for a sequence of folded lines + used++; + } else { + used += plines_win(curwin, bot, true); + } } if (used > curwin->w_height_inner) { break; @@ -1554,12 +1553,12 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) validate_botline(curwin); } - /* The lines of the cursor line itself are always used. */ - used = plines_nofill(cln); + // The lines of the cursor line itself are always used. + used = plines_win_nofill(curwin, cln, true); - /* If the cursor is below botline, we will at least scroll by the height - * of the cursor line. Correct for empty lines, which are really part of - * botline. */ + // If the cursor is below botline, we will at least scroll by the height + // of the cursor line. Correct for empty lines, which are really part of + // botline. if (cln >= curwin->w_botline) { scrolled = used; if (cln == curwin->w_botline) @@ -1703,7 +1702,7 @@ void scroll_cursor_halfway(int atend) loff.lnum = boff.lnum = curwin->w_cursor.lnum; (void)hasFolding(loff.lnum, &loff.lnum, &boff.lnum); - int used = plines_nofill(loff.lnum); + int used = plines_win_nofill(curwin, loff.lnum, true); loff.fill = 0; boff.fill = 0; linenr_T topline = loff.lnum; @@ -1808,17 +1807,19 @@ void cursor_correct(void) int below = curwin->w_filler_rows; /* screen lines below botline */ while ((above < above_wanted || below < below_wanted) && topline < botline) { if (below < below_wanted && (below <= above || above >= above_wanted)) { - if (hasFolding(botline, &botline, NULL)) - ++below; - else - below += plines(botline); - --botline; + if (hasFolding(botline, &botline, NULL)) { + below++; + } else { + below += plines_win(curwin, botline, true); + } + botline--; } if (above < above_wanted && (above < below || below >= below_wanted)) { - if (hasFolding(topline, NULL, &topline)) - ++above; - else - above += plines_nofill(topline); + if (hasFolding(topline, NULL, &topline)) { + above++; + } else { + above += plines_win_nofill(curwin, topline, true); + } /* Count filler lines below this line as context. */ if (topline < botline) @@ -2046,10 +2047,11 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) { int min_height = curwin->w_height_inner - 2; - if (lp->fill > 0) + if (lp->fill > 0) { lp->height = 1; - else - lp->height = plines_nofill(lp->lnum); + } else { + lp->height = plines_win_nofill(curwin, lp->lnum, true); + } int h1 = lp->height; if (h1 > min_height) return; /* no overlap */ @@ -2119,7 +2121,7 @@ void halfpage(bool flag, linenr_T Prenum) n--; curwin->w_topfill--; } else { - i = plines_nofill(curwin->w_topline); + i = plines_win_nofill(curwin, curwin->w_topline, true); n -= i; if (n < 0 && scrolled > 0) break; @@ -2145,12 +2147,12 @@ void halfpage(bool flag, linenr_T Prenum) else { room += i; do { - i = plines(curwin->w_botline); - if (i > room) + i = plines_win(curwin, curwin->w_botline, true); + if (i > room) { break; - (void)hasFolding(curwin->w_botline, NULL, - &curwin->w_botline); - ++curwin->w_botline; + } + (void)hasFolding(curwin->w_botline, NULL, &curwin->w_botline); + curwin->w_botline++; room -= i; } while (curwin->w_botline <= curbuf->b_ml.ml_line_count); } @@ -2179,7 +2181,7 @@ void halfpage(bool flag, linenr_T Prenum) n--; curwin->w_topfill++; } else { - i = plines_nofill(curwin->w_topline - 1); + i = plines_win_nofill(curwin, curwin->w_topline - 1, true); n -= i; if (n < 0 && scrolled > 0) break; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 44cdc09c0b..2a530db934 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -45,6 +45,7 @@ #include "nvim/mouse.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/screen.h" #include "nvim/search.h" @@ -92,8 +93,6 @@ static linenr_T resel_VIsual_line_count; /* number of lines */ static colnr_T resel_VIsual_vcol; /* nr of cols or end col */ static int VIsual_mode_orig = NUL; /* saved Visual mode */ -static int restart_VIsual_select = 0; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "normal.c.generated.h" @@ -1188,7 +1187,7 @@ static void normal_check_interrupt(NormalState *s) && s->previous_got_int) { // Typed two CTRL-C in a row: go back to ex mode as if "Q" was // used and keep "got_int" set, so that it aborts ":g". - exmode_active = EXMODE_NORMAL; + exmode_active = true; State = NORMAL; } else if (!global_busy || !exmode_active) { if (!quit_more) { @@ -1277,6 +1276,15 @@ static void normal_redraw(NormalState *s) redrawWinline(curwin, curwin->w_cursor.lnum); } + // Might need to update for 'cursorline'. + // When 'cursorlineopt' is "screenline" need to redraw always. + if (curwin->w_p_cul + && (curwin->w_last_cursorline != curwin->w_cursor.lnum + || (curwin->w_p_culopt_flags & CULOPT_SCRLINE)) + && !char_avail()) { + redraw_later(curwin, VALID); + } + if (VIsual_active) { update_curbuf(INVERTED); // update inverted part } else if (must_redraw) { @@ -1340,7 +1348,7 @@ static int normal_check(VimState *state) quit_more = false; // If skip redraw is set (for ":" in wait_return()), don't redraw now. - // If there is nothing in the stuff_buffer or do_redraw is TRUE, + // If there is nothing in the stuff_buffer or do_redraw is true, // update cursor and redraw. if (skip_redraw || exmode_active) { skip_redraw = false; @@ -1398,7 +1406,7 @@ static int normal_check(VimState *state) if (s->noexmode) { return 0; } - do_exmode(exmode_active == EXMODE_VIM); + do_exmode(); return -1; } @@ -4652,7 +4660,7 @@ static void nv_exmode(cmdarg_T *cap) if (VIsual_active) { vim_beep(BO_EX); } else if (!checkclearop(cap->oap)) { - do_exmode(false); + do_exmode(); } } @@ -5115,11 +5123,13 @@ static void nv_scroll(cmdarg_T *cap) --n; break; } - used += plines(curwin->w_topline + n); - if (used >= half) + used += plines_win(curwin, curwin->w_topline + n, true); + if (used >= half) { break; - if (hasFolding(curwin->w_topline + n, NULL, &lnum)) + } + if (hasFolding(curwin->w_topline + n, NULL, &lnum)) { n = lnum - curwin->w_topline; + } } if (n > 0 && used > curwin->w_height_inner) { n--; @@ -6554,9 +6564,9 @@ static void n_start_visual_mode(int c) VIsual_mode = c; VIsual_active = true; VIsual_reselect = true; - /* Corner case: the 0 position in a tab may change when going into - * virtualedit. Recalculate curwin->w_cursor to avoid bad hilighting. - */ + // Corner case: the 0 position in a tab may change when going into + // virtualedit. Recalculate curwin->w_cursor to avoid bad highlighting. + // if (c == Ctrl_V && (ve_flags & VE_BLOCK) && gchar_cursor() == TAB) { validate_virtcol(); coladvance(curwin->w_virtcol); @@ -7101,8 +7111,9 @@ static void nv_g_cmd(cmdarg_T *cap) break; } - if (!checkclearopq(oap)) - do_exmode(true); + if (!checkclearopq(oap)) { + do_exmode(); + } break; case ',': @@ -8146,10 +8157,8 @@ static void nv_event(cmdarg_T *cap) } } -/* - * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos". - */ -static int mouse_model_popup(void) +/// @return true when 'mousemodel' is set to "popup" or "popup_setpos". +static bool mouse_model_popup(void) { return p_mousem[0] == 'p'; } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 855f63ba7b..a6eda26d75 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -41,6 +41,7 @@ #include "nvim/normal.h" #include "nvim/option.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" @@ -954,7 +955,7 @@ static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data) /* * Stuff string "p" into yank register "regname" as a single line (append if - * uppercase). "p" must have been alloced. + * uppercase). "p" must have been allocated. * * return FAIL for failure, OK otherwise */ @@ -1066,7 +1067,7 @@ do_execreg( if (reg->y_array == NULL) return FAIL; - // Disallow remaping for ":@r". + // Disallow remapping for ":@r". int remap = colon ? REMAP_NONE : REMAP_YES; /* @@ -3069,7 +3070,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } // In an empty buffer the empty line is going to be replaced, include // it in the saved lines. - if ((BUFEMPTY() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) { + if ((buf_is_empty(curbuf) ? + u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) { goto end; } if (dir == FORWARD) { diff --git a/src/nvim/option.c b/src/nvim/option.c index 388bedc043..0595776f79 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -16,8 +16,6 @@ // - If it's a numeric option, add any necessary bounds checks to // set_num_option(). // - If it's a list of flags, add some code in do_set(), search for WW_ALL. -// - When adding an option with expansion (P_EXPAND), but with a different -// default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP. // - Add documentation! doc/options.txt, and any other related places. // - Add an entry in runtime/optwin.vim. @@ -208,12 +206,10 @@ typedef struct vimoption { // buffer-local option: global value idopt_T indir; // global option: PV_NONE; // local option: indirect option index - char_u *def_val[2]; // default values for variable (vi and vim) + char_u *def_val; // default values for variable (neovim!!) LastSet last_set; // script in which the option was last set } vimoption_T; -#define VI_DEFAULT 0 // def_val[VI_DEFAULT] is Vi default value -#define VIM_DEFAULT 1 // def_val[VIM_DEFAULT] is Vim default value /* * Flags @@ -232,8 +228,6 @@ typedef struct vimoption { // use free() when assigning new value #define P_WAS_SET 0x100U // option has been set/reset #define P_NO_MKRC 0x200U // don't include in :mkvimrc output -#define P_VI_DEF 0x400U // Use Vi default for Vim -#define P_VIM 0x800U // Vim option // when option changed, what to display: #define P_RSTAT 0x1000U ///< redraw status lines @@ -459,7 +453,7 @@ void set_init_1(bool clean_arg) buf[j] = NUL; opt_idx = findoption("cdpath"); if (opt_idx >= 0) { - options[opt_idx].def_val[VI_DEFAULT] = buf; + options[opt_idx].def_val = buf; options[opt_idx].flags |= P_DEF_ALLOCED; } else { xfree(buf); // cannot happen @@ -527,7 +521,7 @@ void set_init_1(bool clean_arg) check_win_options(curwin); check_options(); - // Set all options to their Vim default + // Set all options to their default value set_options_default(OPT_FREE); // set 'laststatus' @@ -563,15 +557,10 @@ void set_init_1(bool clean_arg) if (p != NULL) { p = xstrdup(p); *(char **)options[opt_idx].var = p; - /* VIMEXP - * Defaults for all expanded options are currently the same for Vi - * and Vim. When this changes, add some code here! Also need to - * split P_DEF_ALLOCED in two. - */ if (options[opt_idx].flags & P_DEF_ALLOCED) { - xfree(options[opt_idx].def_val[VI_DEFAULT]); + xfree(options[opt_idx].def_val); } - options[opt_idx].def_val[VI_DEFAULT] = (char_u *)p; + options[opt_idx].def_val = (char_u *)p; options[opt_idx].flags |= P_DEF_ALLOCED; } } @@ -614,39 +603,34 @@ void set_init_1(bool clean_arg) /// Set an option to its default value. /// This does not take care of side effects! -static void -set_option_default( - int opt_idx, - int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL - int compatible // use Vi default value -) +/// +/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL +static void set_option_default(int opt_idx, int opt_flags) { char_u *varp; // pointer to variable for current option - int dvi; // index in def_val[] int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags); uint32_t flags = options[opt_idx].flags; if (varp != NULL) { // skip hidden option, nothing to do for it - dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT; if (flags & P_STRING) { /* Use set_string_option_direct() for local options to handle * freeing and allocating the value. */ if (options[opt_idx].indir != PV_NONE) { set_string_option_direct(NULL, opt_idx, - options[opt_idx].def_val[dvi], opt_flags, 0); + options[opt_idx].def_val, opt_flags, 0); } else { if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) { free_string_option(*(char_u **)(varp)); } - *(char_u **)varp = options[opt_idx].def_val[dvi]; + *(char_u **)varp = options[opt_idx].def_val; options[opt_idx].flags &= ~P_ALLOCED; } } else if (flags & P_NUM) { if (options[opt_idx].indir == PV_SCROLL) { win_comp_scroll(curwin); } else { - long def_val = (long)options[opt_idx].def_val[dvi]; + long def_val = (long)options[opt_idx].def_val; if ((long *)varp == &curwin->w_p_so || (long *)varp == &curwin->w_p_siso) { // 'scrolloff' and 'sidescrolloff' local values have a @@ -662,7 +646,7 @@ set_option_default( } } } else { // P_BOOL - *(int *)varp = (int)(intptr_t)options[opt_idx].def_val[dvi]; + *(int *)varp = (int)(intptr_t)options[opt_idx].def_val; #ifdef UNIX // 'modeline' defaults to off for root if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID) { @@ -692,7 +676,7 @@ set_options_default( { for (int i = 0; options[i].fullname; i++) { if (!(options[i].flags & P_NODEFAULT)) { - set_option_default(i, opt_flags, false); + set_option_default(i, opt_flags); } } @@ -716,10 +700,10 @@ static void set_string_default(const char *name, char *val, bool allocated) int opt_idx = findoption(name); if (opt_idx >= 0) { if (options[opt_idx].flags & P_DEF_ALLOCED) { - xfree(options[opt_idx].def_val[VI_DEFAULT]); + xfree(options[opt_idx].def_val); } - options[opt_idx].def_val[VI_DEFAULT] = allocated + options[opt_idx].def_val = allocated ? (char_u *)val : (char_u *)xstrdup(val); options[opt_idx].flags |= P_DEF_ALLOCED; @@ -766,7 +750,7 @@ void set_number_default(char *name, long val) opt_idx = findoption(name); if (opt_idx >= 0) { - options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(intptr_t)val; + options[opt_idx].def_val = (char_u *)(intptr_t)val; } } @@ -781,11 +765,11 @@ void free_all_options(void) free_string_option(*(char_u **)options[i].var); } if (options[i].flags & P_DEF_ALLOCED) { - free_string_option(options[i].def_val[VI_DEFAULT]); + free_string_option(options[i].def_val); } } else if (options[i].var != VAR_WIN && (options[i].flags & P_STRING)) { // buffer-local option: free global value - free_string_option(*(char_u **)options[i].var); + clear_string_option((char_u **)options[i].var); } } } @@ -804,7 +788,7 @@ void set_init_2(bool headless) // which results in the actual value computed from the window height. idx = findoption("scroll"); if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) { - set_option_default(idx, OPT_LOCAL, false); + set_option_default(idx, OPT_LOCAL); } comp_col(); @@ -850,11 +834,11 @@ void set_init_3(void) ) { if (do_sp) { p_sp = (char_u *)"|& tee"; - options[idx_sp].def_val[VI_DEFAULT] = p_sp; + options[idx_sp].def_val = p_sp; } if (do_srr) { p_srr = (char_u *)">&"; - options[idx_srr].def_val[VI_DEFAULT] = p_srr; + options[idx_srr].def_val = p_srr; } } else if (fnamecmp(p, "sh") == 0 || fnamecmp(p, "ksh") == 0 @@ -870,17 +854,17 @@ void set_init_3(void) // Always use POSIX shell style redirection if we reach this if (do_sp) { p_sp = (char_u *)"2>&1| tee"; - options[idx_sp].def_val[VI_DEFAULT] = p_sp; + options[idx_sp].def_val = p_sp; } if (do_srr) { p_srr = (char_u *)">%s 2>&1"; - options[idx_srr].def_val[VI_DEFAULT] = p_srr; + options[idx_srr].def_val = p_srr; } } xfree(p); } - if (BUFEMPTY()) { + if (buf_is_empty(curbuf)) { int idx_ffs = findoption_len(S_LEN("ffs")); // Apply the first entry of 'fileformats' to the initial buffer. @@ -941,12 +925,12 @@ void set_title_defaults(void) */ idx1 = findoption("title"); if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { - options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0; + options[idx1].def_val = (char_u *)(intptr_t)0; p_title = 0; } idx1 = findoption("icon"); if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { - options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0; + options[idx1].def_val = (char_u *)(intptr_t)0; p_icon = 0; } } @@ -986,7 +970,6 @@ int do_set( int adding; // "opt+=arg" int prepending; // "opt^=arg" int removing; // "opt-=arg" - int cp_val = 0; if (*arg == NUL) { showoptions(0, opt_flags); @@ -1157,13 +1140,10 @@ int do_set( if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL) { arg += len; - cp_val = false; if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i') { - if (arg[3] == 'm') { // "opt&vim": set to Vim default - cp_val = false; + if (arg[3] == 'm') { // "opt&vim": set to Vim default arg += 3; - } else { // "opt&vi": set to Vi default - cp_val = true; + } else { // "opt&vi": set to Vi default arg += 2; } } @@ -1174,10 +1154,10 @@ int do_set( } } - /* - * allow '=' and ':' as MSDOS command.com allows only one - * '=' character per "set" command line. grrr. (jw) - */ + // + // allow '=' and ':' as MS-DOS command.com allows only one + // '=' character per "set" command line. grrr. (jw) + // if (nextchar == '?' || (prefix == 1 && vim_strchr((char_u *)"=:&<", nextchar) == NULL @@ -1230,9 +1210,7 @@ int do_set( if (nextchar == '!') { value = *(int *)(varp) ^ 1; } else if (nextchar == '&') { - value = (int)(intptr_t)options[opt_idx].def_val[ - ((flags & P_VI_DEF) || cp_val) - ? VI_DEFAULT : VIM_DEFAULT]; + value = (int)(intptr_t)options[opt_idx].def_val; } else if (nextchar == '<') { // For 'autoread' -1 means to use global value. if ((int *)varp == &curbuf->b_p_ar @@ -1277,8 +1255,7 @@ int do_set( // other error arg++; if (nextchar == '&') { - value = (long)(intptr_t)options[opt_idx].def_val[ - ((flags & P_VI_DEF) || cp_val) ? VI_DEFAULT : VIM_DEFAULT]; + value = (long)(intptr_t)options[opt_idx].def_val; } else if (nextchar == '<') { // For 'undolevels' NO_LOCAL_UNDOLEVEL means to // use the global value. @@ -1355,14 +1332,12 @@ int do_set( origval = oldval; } - if (nextchar == '&') { // set to default val - newval = options[opt_idx].def_val[ - ((flags & P_VI_DEF) || cp_val) - ? VI_DEFAULT : VIM_DEFAULT]; - /* expand environment variables and ~ (since the - * default value was already expanded, only - * required when an environment variable was set - * later */ + if (nextchar == '&') { // set to default val + newval = options[opt_idx].def_val; + // expand environment variables and ~ (since the + // default value was already expanded, only + // required when an environment variable was set + // later new_value_alloced = true; if (newval == NULL) { newval = empty_option; @@ -1433,22 +1408,19 @@ int do_set( *errbuf = NUL; i = getdigits_int(&arg, true, 0); if (i & 1) { - STRCAT(errbuf, "b,"); + STRLCAT(errbuf, "b,", sizeof(errbuf)); } if (i & 2) { - STRCAT(errbuf, "s,"); + STRLCAT(errbuf, "s,", sizeof(errbuf)); } if (i & 4) { - STRCAT(errbuf, "h,l,"); + STRLCAT(errbuf, "h,l,", sizeof(errbuf)); } if (i & 8) { - STRCAT(errbuf, "<,>,"); + STRLCAT(errbuf, "<,>,", sizeof(errbuf)); } if (i & 16) { - STRCAT(errbuf, "[,],"); - } - if (*errbuf != NUL) { // remove trailing , - errbuf[STRLEN(errbuf) - 1] = NUL; + STRLCAT(errbuf, "[,],", sizeof(errbuf)); } save_arg = arg; arg = errbuf; @@ -1987,6 +1959,7 @@ static void didset_options(void) briopt_check(curwin); // initialize the table for 'breakat'. fill_breakat_flags(); + fill_culopt_flags(NULL, curwin); } // More side effects of setting options. @@ -2436,6 +2409,11 @@ did_set_string_option( os_setenv("VIMRUNTIME", "", 1); didset_vimruntime = false; } + } else if (varp == &curwin->w_p_culopt + || gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt' + if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) { + errmsg = e_invarg; + } } else if (varp == &curwin->w_p_cc) { // 'colorcolumn' errmsg = check_colorcolumn(curwin); } else if (varp == &p_hlg) { // 'helplang' @@ -2719,7 +2697,7 @@ ambw_end: : opt_idx); // Update free_oldval now that we have the opt_idx for 'shada', otherwise // there would be a disconnect between the check for P_ALLOCED at the start - // of the function and the set of P_ALLOCED at the end of the fuction. + // of the function and the set of P_ALLOCED at the end of the function. free_oldval = (options[opt_idx].flags & P_ALLOCED); for (s = p_shada; *s; ) { // Check it's a valid character @@ -3837,22 +3815,19 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, // any changes in between. if (curbuf->b_p_udf || p_udf) { char_u hash[UNDO_HASH_SIZE]; - buf_T *save_curbuf = curbuf; FOR_ALL_BUFFERS(bp) { - curbuf = bp; // When 'undofile' is set globally: for every buffer, otherwise // only for the current buffer: Try to read in the undofile, // if one exists, the buffer wasn't changed and the buffer was // loaded - if ((curbuf == save_curbuf + if ((curbuf == bp || (opt_flags & OPT_GLOBAL) || opt_flags == 0) - && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) { - u_compute_hash(hash); - u_read_undo(NULL, hash, curbuf->b_fname); + && !bufIsChanged(bp) && bp->b_ml.ml_mfp != NULL) { + u_compute_hash(bp, hash); + u_read_undo(NULL, hash, bp->b_fname); } } - curbuf = save_curbuf; } } else if ((int *)varp == &curbuf->b_p_ro) { // when 'readonly' is reset globally, also reset readonlymode @@ -5094,20 +5069,17 @@ showoptions( /// Return true if option "p" has its default value. static int optval_default(vimoption_T *p, char_u *varp) { - int dvi; - if (varp == NULL) { return true; // hidden option is always at default } - dvi = (p->flags & P_VI_DEF) ? VI_DEFAULT : VIM_DEFAULT; if (p->flags & P_NUM) { - return *(long *)varp == (long)(intptr_t)p->def_val[dvi]; + return *(long *)varp == (long)(intptr_t)p->def_val; } if (p->flags & P_BOOL) { - return *(int *)varp == (int)(intptr_t)p->def_val[dvi]; + return *(int *)varp == (int)(intptr_t)p->def_val; } // P_STRING - return STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0; + return STRCMP(*(char_u **)varp, p->def_val) == 0; } /// Send update to UIs with values of UI relevant options @@ -5363,7 +5335,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, home_replace(NULL, *valuep, buf, size, false); // If the option value is longer than MAXPATHL, we need to append - // earch comma separated part of the option sperately, so that it + // search comma separated part of the option separately, so that it // can be expanded when read back. if (size >= MAXPATHL && (flags & P_COMMA) != 0 && vim_strchr(*valuep, ',') != NULL) { @@ -5683,6 +5655,7 @@ static char_u *get_varp(vimoption_T *p) case PV_SPELL: return (char_u *)&(curwin->w_p_spell); case PV_CUC: return (char_u *)&(curwin->w_p_cuc); case PV_CUL: return (char_u *)&(curwin->w_p_cul); + case PV_CULOPT: return (char_u *)&(curwin->w_p_culopt); case PV_CC: return (char_u *)&(curwin->w_p_cc); case PV_DIFF: return (char_u *)&(curwin->w_p_diff); case PV_FDC: return (char_u *)&(curwin->w_p_fdc); @@ -5830,6 +5803,7 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_spell = from->wo_spell; to->wo_cuc = from->wo_cuc; to->wo_cul = from->wo_cul; + to->wo_culopt = vim_strsave(from->wo_culopt); to->wo_cc = vim_strsave(from->wo_cc); to->wo_diff = from->wo_diff; to->wo_diff_saved = from->wo_diff_saved; @@ -5880,6 +5854,7 @@ static void check_winopt(winopt_T *wop) check_string_option(&wop->wo_scl); check_string_option(&wop->wo_rlc); check_string_option(&wop->wo_stl); + check_string_option(&wop->wo_culopt); check_string_option(&wop->wo_cc); check_string_option(&wop->wo_cocu); check_string_option(&wop->wo_briopt); @@ -5902,6 +5877,7 @@ void clear_winopt(winopt_T *wop) clear_string_option(&wop->wo_scl); clear_string_option(&wop->wo_rlc); clear_string_option(&wop->wo_stl); + clear_string_option(&wop->wo_culopt); clear_string_option(&wop->wo_cc); clear_string_option(&wop->wo_cocu); clear_string_option(&wop->wo_briopt); @@ -5914,6 +5890,7 @@ void didset_window_options(win_T *wp) { check_colorcolumn(wp); briopt_check(wp); + fill_culopt_flags(NULL, wp); set_chars_option(wp, &wp->w_p_fcs, true); set_chars_option(wp, &wp->w_p_lcs, true); parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl @@ -6156,7 +6133,7 @@ void reset_modifiable(void) p_ma = false; opt_idx = findoption("ma"); if (opt_idx >= 0) { - options[opt_idx].def_val[VI_DEFAULT] = false; + options[opt_idx].def_val = false; } } @@ -6855,7 +6832,7 @@ static void paste_option_changed(void) /// vimrc_found() - Called when a vimrc or "VIMINIT" has been found. /// -/// Set the values for options that didn't get set yet to the Vim defaults. +/// Set the values for options that didn't get set yet to the defaults. /// When "fname" is not NULL, use it to set $"envname" when it wasn't set yet. void vimrc_found(char_u *fname, char_u *envname) { @@ -6921,6 +6898,49 @@ static void fill_breakat_flags(void) } } +/// fill_culopt_flags() -- called when 'culopt' changes value +static int fill_culopt_flags(char_u *val, win_T *wp) +{ + char_u *p; + char_u culopt_flags_new = 0; + + if (val == NULL) { + p = wp->w_p_culopt; + } else { + p = val; + } + while (*p != NUL) { + if (STRNCMP(p, "line", 4) == 0) { + p += 4; + culopt_flags_new |= CULOPT_LINE; + } else if (STRNCMP(p, "both", 4) == 0) { + p += 4; + culopt_flags_new |= CULOPT_LINE | CULOPT_NBR; + } else if (STRNCMP(p, "number", 6) == 0) { + p += 6; + culopt_flags_new |= CULOPT_NBR; + } else if (STRNCMP(p, "screenline", 10) == 0) { + p += 10; + culopt_flags_new |= CULOPT_SCRLINE; + } + + if (*p != ',' && *p != NUL) { + return FAIL; + } + if (*p == ',') { + p++; + } + } + + // Can't have both "line" and "screenline". + if ((culopt_flags_new & CULOPT_LINE) && (culopt_flags_new & CULOPT_SCRLINE)) { + return FAIL; + } + wp->w_p_culopt_flags = culopt_flags_new; + + return OK; +} + /// Check an option that can be a range of string values. /// /// Return OK for correct value, FAIL otherwise. @@ -7406,6 +7426,7 @@ static bool briopt_check(win_T *wp) int bri_shift = 0; int bri_min = 20; bool bri_sbr = false; + int bri_list = 0; char_u *p = wp->w_p_briopt; while (*p != NUL) @@ -7425,6 +7446,9 @@ static bool briopt_check(win_T *wp) { p += 3; bri_sbr = true; + } else if (STRNCMP(p, "list:", 5) == 0) { + p += 5; + bri_list = (int)getdigits(&p, false, 0); } if (*p != ',' && *p != NUL) { return false; @@ -7437,6 +7461,7 @@ static bool briopt_check(win_T *wp) wp->w_briopt_shift = bri_shift; wp->w_briopt_min = bri_min; wp->w_briopt_sbr = bri_sbr; + wp->w_briopt_list = bri_list; return true; } @@ -7649,6 +7674,12 @@ int win_signcol_configured(win_T *wp, int *is_fixed) return ret; } +// Get the local or global value of 'showbreak'. +char_u *get_showbreak_value(win_T *win FUNC_ATTR_UNUSED) +{ + return p_sbr; +} + /// Get window or buffer local options dict_T *get_winbuf_options(const int bufopt) FUNC_ATTR_WARN_UNUSED_RESULT @@ -7749,8 +7780,7 @@ static Dictionary vimoption2dict(vimoption_T *opt) const char *type; Object def; // TODO(bfredl): do you even nocp? - char_u *def_val = opt->def_val[(opt->flags & P_VI_DEF) - ? VI_DEFAULT : VIM_DEFAULT]; + char_u *def_val = opt->def_val; if (opt->flags & P_STRING) { type = "string"; def = CSTR_TO_OBJ(def_val ? (char *)def_val : ""); diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index beb62a6a0b..97ada9eb25 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -276,10 +276,10 @@ enum { }) // flags used for parsed 'wildmode' -#define WIM_FULL 1 -#define WIM_LONGEST 2 -#define WIM_LIST 4 -#define WIM_BUFLASTUSED 8 +#define WIM_FULL 0x01 +#define WIM_LONGEST 0x02 +#define WIM_LIST 0x04 +#define WIM_BUFLASTUSED 0x08 // arguments for can_bs() // each defined char should be unique over all values @@ -291,6 +291,11 @@ enum { #define BS_START 's' // "Start" #define BS_NOSTOP 'p' // "nostoP +// flags for the 'culopt' option +#define CULOPT_LINE 0x01 // Highlight complete line +#define CULOPT_SCRLINE 0x02 // Highlight screen line +#define CULOPT_NBR 0x04 // Highlight Number column + #define LISPWORD_VALUE \ "defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object" @@ -459,7 +464,6 @@ EXTERN char_u *p_pmcs; // 'printmbcharset' EXTERN char_u *p_pfn; // 'printfont' EXTERN char_u *p_popt; // 'printoptions' EXTERN char_u *p_header; // 'printheader' -EXTERN int p_prompt; // 'prompt' EXTERN char_u *p_guicursor; // 'guicursor' EXTERN char_u *p_guifont; // 'guifont' EXTERN char_u *p_guifontwide; // 'guifontwide' @@ -740,11 +744,11 @@ EXTERN long p_wd; // 'writedelay' EXTERN int p_force_on; ///< options that cannot be turned off. EXTERN int p_force_off; ///< options that cannot be turned on. -/* - * "indir" values for buffer-local opions. - * These need to be defined globally, so that the BV_COUNT can be used with - * b_p_scriptID[]. - */ +// +// "indir" values for buffer-local options. +// These need to be defined globally, so that the BV_COUNT can be used with +// b_p_scriptID[]. +// enum { BV_AI = 0 , BV_AR @@ -871,6 +875,7 @@ enum { , WV_SPELL , WV_CUC , WV_CUL + , WV_CULOPT , WV_CC , WV_STL , WV_WFH diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 0b09686675..8a45cb69fa 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -10,7 +10,7 @@ -- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil, -- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil, -- modelineexpr=nil, --- expand=nil, nodefault=nil, no_mkrc=nil, vi_def=true, vim=true, +-- expand=nil, nodefault=nil, no_mkrc=nil, -- alloced=nil, -- save_pv_indir=nil, -- redraw={'curswant'}, @@ -55,7 +55,6 @@ return { full_name='aleph', abbreviation='al', short_desc=N_("ASCII code of the letter Aleph (Hebrew)"), type='number', scope={'global'}, - vi_def=true, redraw={'curswant'}, varname='p_aleph', defaults={if_true={vi=224}} @@ -64,8 +63,6 @@ return { full_name='arabic', abbreviation='arab', short_desc=N_("Arabic as a default second language"), type='bool', scope={'window'}, - vi_def=true, - vim=true, redraw={'curswant'}, defaults={if_true={vi=false}} }, @@ -73,8 +70,6 @@ return { full_name='arabicshape', abbreviation='arshape', short_desc=N_("do shaping for Arabic characters"), type='bool', scope={'global'}, - vi_def=true, - vim=true, redraw={'all_windows', 'ui_option'}, varname='p_arshape', @@ -84,8 +79,6 @@ return { full_name='allowrevins', abbreviation='ari', short_desc=N_("allow CTRL-_ in Insert and Command-line mode"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_ari', defaults={if_true={vi=false}} }, @@ -93,7 +86,6 @@ return { full_name='ambiwidth', abbreviation='ambw', short_desc=N_("what to do with Unicode chars of ambiguous width"), type='string', scope={'global'}, - vi_def=true, redraw={'all_windows', 'ui_option'}, varname='p_ambw', defaults={if_true={vi="single"}} @@ -102,7 +94,6 @@ return { full_name='autochdir', abbreviation='acd', short_desc=N_("change directory to the file in the current window"), type='bool', scope={'global'}, - vi_def=true, varname='p_acd', defaults={if_true={vi=false}} }, @@ -111,20 +102,19 @@ return { short_desc=N_("take indent for new line from previous line"), type='bool', scope={'buffer'}, varname='p_ai', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='autoread', abbreviation='ar', short_desc=N_("autom. read file when changed outside of Vim"), type='bool', scope={'global', 'buffer'}, varname='p_ar', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='autowrite', abbreviation='aw', short_desc=N_("automatically write file if changed"), type='bool', scope={'global'}, - vi_def=true, varname='p_aw', defaults={if_true={vi=false}} }, @@ -132,7 +122,6 @@ return { full_name='autowriteall', abbreviation='awa', short_desc=N_("as 'autowrite', but works with more commands"), type='bool', scope={'global'}, - vi_def=true, varname='p_awa', defaults={if_true={vi=false}} }, @@ -140,26 +129,22 @@ return { full_name='background', abbreviation='bg', short_desc=N_("\"dark\" or \"light\", used for highlight colors"), type='string', scope={'global'}, - vim=true, redraw={'all_windows'}, varname='p_bg', - defaults={if_true={vi="light",vim="dark"}} + defaults={if_true={vim="dark"}} }, { full_name='backspace', abbreviation='bs', short_desc=N_("how backspace works at start of line"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vim=true, varname='p_bs', - defaults={if_true={vi="", vim="indent,eol,start"}} + defaults={if_true={vim="indent,eol,start"}} }, { full_name='backup', abbreviation='bk', short_desc=N_("keep backup file after overwriting a file"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_bk', defaults={if_true={vi=false}} }, @@ -168,12 +153,11 @@ return { short_desc=N_("make backup as a copy, don't rename the file"), type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, - vim=true, varname='p_bkc', defaults={ condition='UNIX', - if_true={vi="yes", vim="auto"}, - if_false={vi="auto", vim="auto"} + if_true={vim="auto"}, + if_false={vim="auto"} }, }, { @@ -182,7 +166,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, expand='nodefault', varname='p_bdir', defaults={if_true={vi=''}} @@ -192,7 +175,6 @@ return { short_desc=N_("extension used for the backup file"), type='string', scope={'global'}, normal_fname_chars=true, - vi_def=true, varname='p_bex', defaults={if_true={vi="~"}} }, @@ -201,7 +183,6 @@ return { short_desc=N_("no backup for files that match these patterns"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_bsk', defaults={if_true={vi=""}} }, @@ -210,7 +191,6 @@ return { short_desc=N_("do not ring the bell for these reasons"), type='string', list='comma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_bo', defaults={if_true={vi="all"}} }, @@ -218,7 +198,6 @@ return { full_name='binary', abbreviation='bin', short_desc=N_("read/write/edit file in binary mode"), type='bool', scope={'buffer'}, - vi_def=true, redraw={'statuslines'}, varname='p_bin', defaults={if_true={vi=false}} @@ -228,7 +207,6 @@ return { short_desc=N_("a Byte Order Mark to the file"), type='bool', scope={'buffer'}, no_mkrc=true, - vi_def=true, redraw={'statuslines'}, varname='p_bomb', defaults={if_true={vi=false}} @@ -237,7 +215,6 @@ return { full_name='breakat', abbreviation='brk', short_desc=N_("characters that may cause a line break"), type='string', list='flags', scope={'global'}, - vi_def=true, redraw={'all_windows'}, varname='p_breakat', defaults={if_true={vi=" \t!@*-+;:,./?"}} @@ -246,8 +223,6 @@ return { full_name='breakindent', abbreviation='bri', short_desc=N_("wrapped line repeats indent"), type='bool', scope={'window'}, - vi_def=true, - vim=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -256,7 +231,6 @@ return { short_desc=N_("settings for 'breakindent'"), type='string', list='onecomma', scope={'window'}, deny_duplicates=true, - vi_def=true, alloced=true, redraw={'current_buffer'}, defaults={if_true={vi=""}}, @@ -265,7 +239,6 @@ return { full_name='browsedir', abbreviation='bsdir', short_desc=N_("which directory to start browsing in"), type='string', scope={'global'}, - vi_def=true, enable_if=false, }, { @@ -273,7 +246,6 @@ return { short_desc=N_("what to do when buffer is no longer in window"), type='string', scope={'buffer'}, noglob=true, - vi_def=true, alloced=true, varname='p_bh', defaults={if_true={vi=""}} @@ -283,7 +255,6 @@ return { short_desc=N_("whether the buffer shows up in the buffer list"), type='bool', scope={'buffer'}, noglob=true, - vi_def=true, varname='p_bl', defaults={if_true={vi=1}} }, @@ -292,7 +263,6 @@ return { short_desc=N_("special type of buffer"), type='string', scope={'buffer'}, noglob=true, - vi_def=true, alloced=true, varname='p_bt', defaults={if_true={vi=""}} @@ -302,7 +272,6 @@ return { short_desc=N_("specifies how case of letters is changed"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_cmp', defaults={if_true={vi="internal,keepascii"}} }, @@ -311,7 +280,6 @@ return { short_desc=N_("list of directories searched with \":cd\""), type='string', list='comma', scope={'global'}, deny_duplicates=true, - vi_def=true, expand=true, secure=true, varname='p_cdpath', @@ -322,7 +290,7 @@ return { short_desc=N_("used to open the command-line window"), type='string', scope={'global'}, varname='p_cedit', - defaults={if_true={vi="", vim=macros('CTRL_F_STR')}} + defaults={if_true={vim=macros('CTRL_F_STR')}} }, { full_name='channel', @@ -338,7 +306,6 @@ return { short_desc=N_("expression for character encoding conversion"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_ccv', defaults={if_true={vi=""}} }, @@ -346,8 +313,6 @@ return { full_name='cindent', abbreviation='cin', short_desc=N_("do C program indenting"), type='bool', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_cin', defaults={if_true={vi=false}} }, @@ -356,7 +321,6 @@ return { short_desc=N_("keys that trigger indent when 'cindent' is set"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, varname='p_cink', defaults={if_true={vi=indentkeys_default}} @@ -366,7 +330,6 @@ return { short_desc=N_("how to do indenting when 'cindent' is set"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, varname='p_cino', defaults={if_true={vi=""}} @@ -376,7 +339,6 @@ return { short_desc=N_("words where 'si' and 'cin' add an indent"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, varname='p_cinw', defaults={if_true={vi="if,else,while,do,for,switch"}} @@ -386,7 +348,6 @@ return { short_desc=N_("use the clipboard as the unnamed register"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_cb', defaults={if_true={vi=""}} }, @@ -394,7 +355,6 @@ return { full_name='cmdheight', abbreviation='ch', short_desc=N_("number of lines to use for the command-line"), type='number', scope={'global'}, - vi_def=true, redraw={'all_windows'}, varname='p_ch', defaults={if_true={vi=1}} @@ -403,7 +363,6 @@ return { full_name='cmdwinheight', abbreviation='cwh', short_desc=N_("height of the command-line window"), type='number', scope={'global'}, - vi_def=true, varname='p_cwh', defaults={if_true={vi=7}} }, @@ -412,7 +371,6 @@ return { short_desc=N_("columns to highlight"), type='string', list='onecomma', scope={'window'}, deny_duplicates=true, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=""}} }, @@ -421,7 +379,6 @@ return { short_desc=N_("number of columns in the display"), type='number', scope={'global'}, no_mkrc=true, - vi_def=true, redraw={'everything'}, varname='p_columns', defaults={if_true={vi=macros('DFLT_COLS')}} @@ -431,7 +388,6 @@ return { short_desc=N_("patterns that can start a comment line"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, redraw={'curswant'}, varname='p_com', @@ -441,7 +397,6 @@ return { full_name='commentstring', abbreviation='cms', short_desc=N_("template for comments; used for fold marker"), type='string', scope={'buffer'}, - vi_def=true, alloced=true, redraw={'curswant'}, varname='p_cms', @@ -455,7 +410,7 @@ return { varname='p_force_off', -- pri_mkrc isn't needed here, optval_default() -- always returns TRUE for 'compatible' - defaults={if_true={vi=true, vim=false}} + defaults={if_true={vim=false}} }, { full_name='complete', abbreviation='cpt', @@ -464,13 +419,12 @@ return { deny_duplicates=true, alloced=true, varname='p_cpt', - defaults={if_true={vi=".,w,b,u,t,i", vim=".,w,b,u,t"}} + defaults={if_true={vim=".,w,b,u,t"}} }, { full_name='concealcursor', abbreviation='cocu', short_desc=N_("whether concealable text is hidden in cursor line"), type='string', scope={'window'}, - vi_def=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi=""}} @@ -479,7 +433,6 @@ return { full_name='conceallevel', abbreviation='cole', short_desc=N_("whether concealable text is shown or hidden"), type='number', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=0}} }, @@ -488,7 +441,6 @@ return { short_desc=N_("function to be used for Insert mode completion"), type='string', scope={'buffer'}, secure=true, - vi_def=true, alloced=true, varname='p_cfu', defaults={if_true={vi=""}} @@ -498,15 +450,12 @@ return { short_desc=N_("options for Insert mode completion"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_cot', defaults={if_true={vi="menu,preview"}} }, { full_name='completeslash', abbreviation='csl', type='string', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_csl', enable_if='BACKSLASH_IN_FILENAME', defaults={if_true={vi=""}} @@ -515,7 +464,6 @@ return { full_name='confirm', abbreviation='cf', short_desc=N_("ask what to do about unsaved/read-only files"), type='bool', scope={'global'}, - vi_def=true, varname='p_confirm', defaults={if_true={vi=false}} }, @@ -523,8 +471,6 @@ return { full_name='copyindent', abbreviation='ci', short_desc=N_("make 'autoindent' use existing indent structure"), type='bool', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_ci', defaults={if_true={vi=false}} }, @@ -532,17 +478,14 @@ return { full_name='cpoptions', abbreviation='cpo', short_desc=N_("flags for Vi-compatible behavior"), type='string', list='flags', scope={'global'}, - vim=true, redraw={'all_windows'}, varname='p_cpo', - defaults={if_true={vi=macros('CPO_VI'), vim=macros('CPO_VIM')}} + defaults={if_true={vim=macros('CPO_VIM')}} }, { full_name='cscopepathcomp', abbreviation='cspc', short_desc=N_("how many components of the path to show"), type='number', scope={'global'}, - vi_def=true, - vim=true, varname='p_cspc', defaults={if_true={vi=0}} }, @@ -551,7 +494,6 @@ return { short_desc=N_("command to execute cscope"), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_csprg', defaults={if_true={vi="cscope"}} @@ -561,7 +503,6 @@ return { short_desc=N_("use quickfix window for cscope results"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_csqf', defaults={if_true={vi=""}} }, @@ -569,8 +510,6 @@ return { full_name='cscoperelative', abbreviation='csre', short_desc=N_("Use cscope.out path basename as prefix"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_csre', defaults={if_true={vi=0}} }, @@ -578,8 +517,6 @@ return { full_name='cscopetag', abbreviation='cst', short_desc=N_("use cscope for tag commands"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_cst', defaults={if_true={vi=0}} }, @@ -587,8 +524,6 @@ return { full_name='cscopetagorder', abbreviation='csto', short_desc=N_("determines \":cstag\" search order"), type='number', scope={'global'}, - vi_def=true, - vim=true, varname='p_csto', defaults={if_true={vi=0}} }, @@ -596,8 +531,6 @@ return { full_name='cscopeverbose', abbreviation='csverb', short_desc=N_("give messages when adding a cscope database"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_csverbose', defaults={if_true={vi=1}} }, @@ -605,7 +538,6 @@ return { full_name='cursorbind', abbreviation='crb', short_desc=N_("move cursor in window as it moves in other windows"), type='bool', scope={'window'}, - vi_def=true, pv_name='p_crbind', defaults={if_true={vi=false}} }, @@ -613,7 +545,6 @@ return { full_name='cursorcolumn', abbreviation='cuc', short_desc=N_("highlight the screen column of the cursor"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window_only'}, defaults={if_true={vi=false}} }, @@ -621,15 +552,21 @@ return { full_name='cursorline', abbreviation='cul', short_desc=N_("highlight the screen line of the cursor"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window_only'}, defaults={if_true={vi=false}} }, { + full_name='cursorlineopt', abbreviation='culopt', + short_desc=N_("settings for 'cursorline'"), + type='string', list='onecomma', scope={'window'}, + deny_duplicates=true, + redraw={'current_window_only'}, + defaults={if_true={vi="both"}} + }, + { full_name='debug', short_desc=N_("to \"msg\" to see all error messages"), type='string', scope={'global'}, - vi_def=true, varname='p_debug', defaults={if_true={vi=""}} }, @@ -637,7 +574,6 @@ return { full_name='define', abbreviation='def', short_desc=N_("pattern to be used to find a macro definition"), type='string', scope={'global', 'buffer'}, - vi_def=true, alloced=true, redraw={'curswant'}, varname='p_def', @@ -647,8 +583,6 @@ return { full_name='delcombine', abbreviation='deco', short_desc=N_("delete combining characters on their own"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_deco', defaults={if_true={vi=false}} }, @@ -658,7 +592,6 @@ return { type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, normal_dname_chars=true, - vi_def=true, expand=true, varname='p_dict', defaults={if_true={vi=""}} @@ -668,7 +601,6 @@ return { short_desc=N_("diff mode for the current window"), type='bool', scope={'window'}, noglob=true, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -677,7 +609,6 @@ return { short_desc=N_("expression used to obtain a diff file"), type='string', scope={'global'}, secure=true, - vi_def=true, redraw={'curswant'}, varname='p_dex', defaults={if_true={vi=""}} @@ -687,7 +618,6 @@ return { short_desc=N_("options for using diff mode"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, alloced=true, redraw={'current_window'}, varname='p_dip', @@ -697,8 +627,6 @@ return { full_name='digraph', abbreviation='dg', short_desc=N_("enable the entering of digraphs in Insert mode"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_dg', defaults={if_true={vi=false}} }, @@ -708,7 +636,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, expand='nodefault', varname='p_dir', defaults={if_true={vi=''}} @@ -718,16 +645,14 @@ return { short_desc=N_("list of flags for how to display text"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vim=true, redraw={'all_windows'}, varname='p_dy', - defaults={if_true={vi="", vim="lastline,msgsep"}} + defaults={if_true={vim="lastline,msgsep"}} }, { full_name='eadirection', abbreviation='ead', short_desc=N_("in which direction 'equalalways' works"), type='string', scope={'global'}, - vi_def=true, varname='p_ead', defaults={if_true={vi="both"}} }, @@ -735,7 +660,6 @@ return { full_name='edcompatible', abbreviation='ed', short_desc=N_("No description"), type='bool', scope={'global'}, - vi_def=true, varname='p_force_off', defaults={if_true={vi=false}} }, @@ -743,7 +667,6 @@ return { full_name='emoji', abbreviation='emo', short_desc=N_("No description"), type='bool', scope={'global'}, - vi_def=true, redraw={'all_windows', 'ui_option'}, varname='p_emoji', defaults={if_true={vi=true}} @@ -753,7 +676,6 @@ return { short_desc=N_("encoding used internally"), type='string', scope={'global'}, deny_in_modelines=true, - vi_def=true, varname='p_enc', defaults={if_true={vi=macros('ENC_DFLT')}} }, @@ -762,7 +684,6 @@ return { short_desc=N_("write <EOL> for last line in file"), type='bool', scope={'buffer'}, no_mkrc=true, - vi_def=true, redraw={'statuslines'}, varname='p_eol', defaults={if_true={vi=true}} @@ -771,7 +692,6 @@ return { full_name='equalalways', abbreviation='ea', short_desc=N_("windows are automatically made the same size"), type='bool', scope={'global'}, - vi_def=true, redraw={'all_windows'}, varname='p_ea', defaults={if_true={vi=true}} @@ -781,7 +701,6 @@ return { short_desc=N_("external program to use for \"=\" command"), type='string', scope={'global', 'buffer'}, secure=true, - vi_def=true, expand=true, varname='p_ep', defaults={if_true={vi=""}} @@ -790,7 +709,6 @@ return { full_name='errorbells', abbreviation='eb', short_desc=N_("ring the bell for error messages"), type='bool', scope={'global'}, - vi_def=true, varname='p_eb', defaults={if_true={vi=false}} }, @@ -799,7 +717,6 @@ return { short_desc=N_("name of the errorfile for the QuickFix mode"), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_ef', defaults={if_true={vi=macros('DFLT_ERRORFILE')}} @@ -809,7 +726,6 @@ return { short_desc=N_("description of the lines in the error file"), type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, - vi_def=true, varname='p_efm', defaults={if_true={vi=macros('DFLT_EFM')}} }, @@ -818,7 +734,6 @@ return { short_desc=N_("autocommand events that are ignored"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_ei', defaults={if_true={vi=""}} }, @@ -826,8 +741,6 @@ return { full_name='expandtab', abbreviation='et', short_desc=N_("use spaces when <Tab> is inserted"), type='bool', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_et', defaults={if_true={vi=false}} }, @@ -836,7 +749,6 @@ return { short_desc=N_("read .nvimrc and .exrc in the current directory"), type='bool', scope={'global'}, secure=true, - vi_def=true, varname='p_exrc', defaults={if_true={vi=false}} }, @@ -845,7 +757,6 @@ return { short_desc=N_("file encoding for multi-byte text"), type='string', scope={'buffer'}, no_mkrc=true, - vi_def=true, alloced=true, redraw={'statuslines', 'current_buffer'}, varname='p_fenc', @@ -856,7 +767,6 @@ return { short_desc=N_("automatically detected character encodings"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_fencs', defaults={if_true={vi="ucs-bom,utf-8,default,latin1"}} }, @@ -865,7 +775,6 @@ return { short_desc=N_("file format used for file I/O"), type='string', scope={'buffer'}, no_mkrc=true, - vi_def=true, alloced=true, redraw={'curswant', 'statuslines'}, varname='p_ff', @@ -876,15 +785,13 @@ return { short_desc=N_("automatically detected values for 'fileformat'"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vim=true, varname='p_ffs', - defaults={if_true={vi=macros('DFLT_FFS_VI'), vim=macros('DFLT_FFS_VIM')}} + defaults={if_true={vim=macros('DFLT_FFS_VIM')}} }, { full_name='fileignorecase', abbreviation='fic', short_desc=N_("ignore case when using file names"), type='bool', scope={'global'}, - vi_def=true, varname='p_fic', defaults={ condition='CASE_INSENSITIVE_FILENAME', @@ -898,7 +805,6 @@ return { type='string', scope={'buffer'}, noglob=true, normal_fname_chars=true, - vi_def=true, alloced=true, expand=true, varname='p_ft', @@ -909,7 +815,6 @@ return { short_desc=N_("characters to use for displaying special items"), type='string', list='onecomma', scope={'global', 'window'}, deny_duplicates=true, - vi_def=true, alloced=true, redraw={'current_window'}, varname='p_fcs', @@ -919,7 +824,6 @@ return { full_name='fixendofline', abbreviation='fixeol', short_desc=N_("make sure last line in file has <EOL>"), type='bool', scope={'buffer'}, - vi_def=true, redraw={'statuslines'}, varname='p_fixeol', defaults={if_true={vi=true}} @@ -929,7 +833,6 @@ return { short_desc=N_("close a fold when the cursor leaves it"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, redraw={'current_window'}, varname='p_fcl', defaults={if_true={vi=""}} @@ -938,7 +841,6 @@ return { full_name='foldcolumn', abbreviation='fdc', short_desc=N_("width of the column used to indicate folds"), type='string', scope={'window'}, - vi_def=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi="0"}} @@ -947,7 +849,6 @@ return { full_name='foldenable', abbreviation='fen', short_desc=N_("set to display all folds open"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=true}} }, @@ -955,8 +856,6 @@ return { full_name='foldexpr', abbreviation='fde', short_desc=N_("expression used when 'foldmethod' is \"expr\""), type='string', scope={'window'}, - vi_def=true, - vim=true, modelineexpr=true, alloced=true, redraw={'current_window'}, @@ -966,8 +865,6 @@ return { full_name='foldignore', abbreviation='fdi', short_desc=N_("ignore lines when 'foldmethod' is \"indent\""), type='string', scope={'window'}, - vi_def=true, - vim=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi="#"}} @@ -976,7 +873,6 @@ return { full_name='foldlevel', abbreviation='fdl', short_desc=N_("close folds with a level higher than this"), type='number', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=0}} }, @@ -984,7 +880,6 @@ return { full_name='foldlevelstart', abbreviation='fdls', short_desc=N_("'foldlevel' when starting to edit a file"), type='number', scope={'global'}, - vi_def=true, redraw={'curswant'}, varname='p_fdls', defaults={if_true={vi=-1}} @@ -994,8 +889,6 @@ return { short_desc=N_("markers used when 'foldmethod' is \"marker\""), type='string', list='onecomma', scope={'window'}, deny_duplicates=true, - vi_def=true, - vim=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi="{{{,}}}"}} @@ -1004,8 +897,6 @@ return { full_name='foldmethod', abbreviation='fdm', short_desc=N_("folding type"), type='string', scope={'window'}, - vi_def=true, - vim=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi="manual"}} @@ -1014,7 +905,6 @@ return { full_name='foldminlines', abbreviation='fml', short_desc=N_("minimum number of lines for a fold to be closed"), type='number', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=1}} }, @@ -1022,7 +912,6 @@ return { full_name='foldnestmax', abbreviation='fdn', short_desc=N_("maximum fold depth"), type='number', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=20}} }, @@ -1031,7 +920,6 @@ return { short_desc=N_("for which commands a fold will be opened"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, redraw={'curswant'}, varname='p_fdo', defaults={if_true={vi="block,hor,mark,percent,quickfix,search,tag,undo"}} @@ -1040,8 +928,6 @@ return { full_name='foldtext', abbreviation='fdt', short_desc=N_("expression used to display for a closed fold"), type='string', scope={'window'}, - vi_def=true, - vim=true, modelineexpr=true, alloced=true, redraw={'current_window'}, @@ -1051,8 +937,6 @@ return { full_name='formatexpr', abbreviation='fex', short_desc=N_("expression used with \"gq\" command"), type='string', scope={'buffer'}, - vi_def=true, - vim=true, modelineexpr=true, alloced=true, varname='p_fex', @@ -1062,16 +946,14 @@ return { full_name='formatoptions', abbreviation='fo', short_desc=N_("how automatic formatting is to be done"), type='string', list='flags', scope={'buffer'}, - vim=true, alloced=true, varname='p_fo', - defaults={if_true={vi=macros('DFLT_FO_VI'), vim=macros('DFLT_FO_VIM')}} + defaults={if_true={vim=macros('DFLT_FO_VIM')}} }, { full_name='formatlistpat', abbreviation='flp', short_desc=N_("pattern used to recognize a list header"), type='string', scope={'buffer'}, - vi_def=true, alloced=true, varname='p_flp', defaults={if_true={vi="^\\s*\\d\\+[\\]:.)}\\t ]\\s*"}} @@ -1081,7 +963,6 @@ return { short_desc=N_("name of external program used with \"gq\" command"), type='string', scope={'global', 'buffer'}, secure=true, - vi_def=true, expand=true, varname='p_fp', defaults={if_true={vi=""}} @@ -1091,7 +972,6 @@ return { short_desc=N_("whether to invoke fsync() after file write"), type='bool', scope={'global'}, secure=true, - vi_def=true, varname='p_fs', defaults={if_true={vi=false}} }, @@ -1099,8 +979,6 @@ return { full_name='gdefault', abbreviation='gd', short_desc=N_("the \":substitute\" flag 'g' is default on"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_gd', defaults={if_true={vi=false}} }, @@ -1109,7 +987,6 @@ return { short_desc=N_("format of 'grepprg' output"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_gefm', defaults={if_true={vi=macros('DFLT_GREPFORMAT')}} }, @@ -1118,7 +995,6 @@ return { short_desc=N_("program to use for \":grep\""), type='string', scope={'global', 'buffer'}, secure=true, - vi_def=true, expand=true, varname='p_gp', defaults={ @@ -1134,7 +1010,6 @@ return { short_desc=N_("GUI: settings for cursor shape and blinking"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_guicursor', defaults={if_true={vi="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"}} }, @@ -1143,7 +1018,6 @@ return { short_desc=N_("GUI: Name(s) of font(s) to be used"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_guifont', redraw={'ui_option'}, defaults={if_true={vi=""}} @@ -1153,7 +1027,6 @@ return { short_desc=N_("list of font names for double-wide characters"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, redraw={'ui_option'}, varname='p_guifontwide', defaults={if_true={vi=""}} @@ -1162,7 +1035,6 @@ return { full_name='guioptions', abbreviation='go', short_desc=N_("GUI: Which components and options are used"), type='string', list='flags', scope={'global'}, - vi_def=true, redraw={'all_windows'}, enable_if=false, }, @@ -1170,7 +1042,6 @@ return { full_name='guitablabel', abbreviation='gtl', short_desc=N_("GUI: custom label for a tab page"), type='string', scope={'global'}, - vi_def=true, modelineexpr=true, redraw={'current_window'}, enable_if=false, @@ -1179,7 +1050,6 @@ return { full_name='guitabtooltip', abbreviation='gtt', short_desc=N_("GUI: custom tooltip for a tab page"), type='string', scope={'global'}, - vi_def=true, redraw={'current_window'}, enable_if=false, }, @@ -1188,7 +1058,6 @@ return { short_desc=N_("full path name of the main help file"), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_hf', defaults={if_true={vi=macros('DFLT_HELPFILE')}} @@ -1197,7 +1066,6 @@ return { full_name='helpheight', abbreviation='hh', short_desc=N_("minimum height of a new help window"), type='number', scope={'global'}, - vi_def=true, varname='p_hh', defaults={if_true={vi=20}} }, @@ -1206,7 +1074,6 @@ return { short_desc=N_("preferred help languages"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_hlg', defaults={if_true={vi=""}} }, @@ -1214,7 +1081,6 @@ return { full_name='hidden', abbreviation='hid', short_desc=N_("don't unload buffer when it is |abandon|ed"), type='bool', scope={'global'}, - vi_def=true, varname='p_hid', defaults={if_true={vi=false}} }, @@ -1223,7 +1089,6 @@ return { short_desc=N_("sets highlighting mode for various occasions"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_hl', defaults={if_true={vi=macros('HIGHLIGHT_INIT')}} }, @@ -1231,16 +1096,13 @@ return { full_name='history', abbreviation='hi', short_desc=N_("number of command-lines that are remembered"), type='number', scope={'global'}, - vim=true, varname='p_hi', - defaults={if_true={vi=0, vim=10000}} + defaults={if_true={vim=10000}} }, { full_name='hkmap', abbreviation='hk', short_desc=N_("Hebrew keyboard mapping"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_hkmap', defaults={if_true={vi=false}} }, @@ -1248,8 +1110,6 @@ return { full_name='hkmapp', abbreviation='hkp', short_desc=N_("phonetic Hebrew keyboard mapping"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_hkmapp', defaults={if_true={vi=false}} }, @@ -1257,16 +1117,14 @@ return { full_name='hlsearch', abbreviation='hls', short_desc=N_("highlight matches with last search pattern"), type='bool', scope={'global'}, - vim=true, redraw={'all_windows'}, varname='p_hls', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='icon', short_desc=N_("Vim set the text of the window icon"), type='bool', scope={'global'}, - vi_def=true, varname='p_icon', defaults={if_true={vi=false}} }, @@ -1274,7 +1132,6 @@ return { full_name='iconstring', short_desc=N_("to use for the Vim icon text"), type='string', scope={'global'}, - vi_def=true, modelineexpr=true, varname='p_iconstring', defaults={if_true={vi=""}} @@ -1283,7 +1140,6 @@ return { full_name='ignorecase', abbreviation='ic', short_desc=N_("ignore case in search patterns"), type='bool', scope={'global'}, - vi_def=true, varname='p_ic', defaults={if_true={vi=false}} }, @@ -1291,7 +1147,6 @@ return { full_name='imcmdline', abbreviation='imc', short_desc=N_("use IM when starting to edit a command line"), type='bool', scope={'global'}, - vi_def=true, enable_if=false, defaults={if_true={vi=false}} }, @@ -1299,7 +1154,6 @@ return { full_name='imdisable', abbreviation='imd', short_desc=N_("do not use the IM in any mode"), type='bool', scope={'global'}, - vi_def=true, enable_if=false, defaults={if_true={vi=false}} }, @@ -1307,7 +1161,6 @@ return { full_name='iminsert', abbreviation='imi', short_desc=N_("use :lmap or IM in Insert mode"), type='number', scope={'buffer'}, - vi_def=true, varname='p_iminsert', pv_name='p_imi', defaults={ if_true={vi=macros('B_IMODE_NONE')}, @@ -1317,7 +1170,6 @@ return { full_name='imsearch', abbreviation='ims', short_desc=N_("use :lmap or IM when typing a search pattern"), type='number', scope={'buffer'}, - vi_def=true, varname='p_imsearch', pv_name='p_ims', defaults={ if_true={vi=macros('B_IMODE_USE_INSERT')}, @@ -1327,7 +1179,6 @@ return { full_name='inccommand', abbreviation='icm', short_desc=N_("Live preview of substitution"), type='string', scope={'global'}, - vi_def=true, redraw={'all_windows'}, varname='p_icm', defaults={if_true={vi=""}} @@ -1336,7 +1187,6 @@ return { full_name='include', abbreviation='inc', short_desc=N_("pattern to be used to find an include file"), type='string', scope={'global', 'buffer'}, - vi_def=true, alloced=true, varname='p_inc', defaults={if_true={vi="^\\s*#\\s*include"}} @@ -1345,7 +1195,6 @@ return { full_name='includeexpr', abbreviation='inex', short_desc=N_("expression used to process an include line"), type='string', scope={'buffer'}, - vi_def=true, modelineexpr=true, alloced=true, varname='p_inex', @@ -1355,16 +1204,13 @@ return { full_name='incsearch', abbreviation='is', short_desc=N_("highlight match while typing search pattern"), type='bool', scope={'global'}, - vim=true, varname='p_is', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='indentexpr', abbreviation='inde', short_desc=N_("expression used to obtain the indent of a line"), type='string', scope={'buffer'}, - vi_def=true, - vim=true, modelineexpr=true, alloced=true, varname='p_inde', @@ -1375,7 +1221,6 @@ return { short_desc=N_("keys that trigger indenting with 'indentexpr'"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, varname='p_indk', defaults={if_true={vi=indentkeys_default}} @@ -1384,7 +1229,6 @@ return { full_name='infercase', abbreviation='inf', short_desc=N_("adjust case of match for keyword completion"), type='bool', scope={'buffer'}, - vi_def=true, varname='p_inf', defaults={if_true={vi=false}} }, @@ -1392,8 +1236,6 @@ return { full_name='insertmode', abbreviation='im', short_desc=N_("start the edit of a file in Insert mode"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_im', defaults={if_true={vi=false}} }, @@ -1402,7 +1244,6 @@ return { short_desc=N_("characters included in file names and pathnames"), type='string', list='comma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_isf', defaults={ condition='BACKSLASH_IN_FILENAME', @@ -1417,7 +1258,6 @@ return { short_desc=N_("characters included in identifiers"), type='string', list='comma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_isi', defaults={ condition='WIN32', @@ -1430,17 +1270,15 @@ return { short_desc=N_("characters included in keywords"), type='string', list='comma', scope={'buffer'}, deny_duplicates=true, - vim=true, alloced=true, varname='p_isk', - defaults={if_true={vi="@,48-57,_", vim="@,48-57,_,192-255"}} + defaults={if_true={vim="@,48-57,_,192-255"}} }, { full_name='isprint', abbreviation='isp', short_desc=N_("printable characters"), type='string', list='comma', scope={'global'}, deny_duplicates=true, - vi_def=true, redraw={'all_windows'}, varname='p_isp', defaults={if_true={vi="@,161-255"} @@ -1450,8 +1288,6 @@ return { full_name='joinspaces', abbreviation='js', short_desc=N_("two spaces after a period with a join command"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_js', defaults={if_true={vi=true}} }, @@ -1461,7 +1297,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_jop', - vim=true, defaults={if_true={vim=''}} }, { @@ -1470,7 +1305,6 @@ return { type='string', scope={'buffer'}, normal_fname_chars=true, pri_mkrc=true, - vi_def=true, alloced=true, redraw={'statuslines', 'current_buffer'}, varname='p_keymap', pv_name='p_kmap', @@ -1481,7 +1315,6 @@ return { short_desc=N_("enable starting/stopping selection with keys"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_km', defaults={if_true={vi=""}} }, @@ -1490,7 +1323,6 @@ return { short_desc=N_("program to use for the \"K\" command"), type='string', scope={'global', 'buffer'}, secure=true, - vi_def=true, expand=true, varname='p_kp', defaults={ @@ -1503,7 +1335,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, varname='p_langmap', defaults={if_true={vi=""}} }, @@ -1512,7 +1343,6 @@ return { short_desc=N_("language to be used for the menus"), type='string', scope={'global'}, normal_fname_chars=true, - vi_def=true, varname='p_lm', defaults={if_true={vi=""}} }, @@ -1521,29 +1351,27 @@ return { short_desc=N_("do not apply 'langmap' to mapped characters"), type='bool', scope={'global'}, varname='p_lnr', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='langremap', abbreviation='lrm', short_desc=N_('No description'), type='bool', scope={'global'}, varname='p_lrm', - defaults={if_true={vi=true, vim=false}} + defaults={if_true={vim=false}} }, { full_name='laststatus', abbreviation='ls', short_desc=N_("tells when last window has status lines"), type='number', scope={'global'}, - vim=true, redraw={'all_windows'}, varname='p_ls', - defaults={if_true={vi=1,vim=2}} + defaults={if_true={vim=2}} }, { full_name='lazyredraw', abbreviation='lz', short_desc=N_("don't redraw while executing macros"), type='bool', scope={'global'}, - vi_def=true, varname='p_lz', defaults={if_true={vi=false}} }, @@ -1551,7 +1379,6 @@ return { full_name='linebreak', abbreviation='lbr', short_desc=N_("wrap long lines at a blank"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -1560,7 +1387,6 @@ return { short_desc=N_("of lines in the display"), type='number', scope={'global'}, no_mkrc=true, - vi_def=true, redraw={'everything'}, varname='p_lines', defaults={if_true={vi=macros('DFLT_ROWS')}} @@ -1569,7 +1395,6 @@ return { full_name='linespace', abbreviation='lsp', short_desc=N_("number of pixel lines to use between characters"), type='number', scope={'global'}, - vi_def=true, redraw={'ui_option'}, varname='p_linespace', defaults={if_true={vi=0}} @@ -1578,7 +1403,6 @@ return { full_name='lisp', short_desc=N_("indenting for Lisp"), type='bool', scope={'buffer'}, - vi_def=true, varname='p_lisp', defaults={if_true={vi=false}} }, @@ -1587,7 +1411,6 @@ return { short_desc=N_("words that change how lisp indenting works"), type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, - vi_def=true, varname='p_lispwords', pv_name='p_lw', defaults={if_true={vi=macros('LISPWORD_VALUE')}} }, @@ -1595,7 +1418,6 @@ return { full_name='list', short_desc=N_("<Tab> and <EOL>"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -1604,17 +1426,15 @@ return { short_desc=N_("characters for displaying in list mode"), type='string', list='onecomma', scope={'global', 'window'}, deny_duplicates=true, - vim=true, alloced=true, redraw={'current_window'}, varname='p_lcs', - defaults={if_true={vi="eol:$", vim="tab:> ,trail:-,nbsp:+"}} + defaults={if_true={vim="tab:> ,trail:-,nbsp:+"}} }, { full_name='loadplugins', abbreviation='lpl', short_desc=N_("load plugin scripts when starting up"), type='bool', scope={'global'}, - vi_def=true, varname='p_lpl', defaults={if_true={vi=true}} }, @@ -1622,7 +1442,6 @@ return { full_name='magic', short_desc=N_("special characters in search patterns"), type='bool', scope={'global'}, - vi_def=true, varname='p_magic', defaults={if_true={vi=true}} }, @@ -1631,7 +1450,6 @@ return { short_desc=N_("name of the errorfile for \":make\""), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_mef', defaults={if_true={vi=""}} @@ -1640,7 +1458,6 @@ return { full_name='makeencoding', abbreviation='menc', short_desc=N_("Converts the output of external commands"), type='string', scope={'global', 'buffer'}, - vi_def=true, varname='p_menc', defaults={if_true={vi=""}} }, @@ -1649,7 +1466,6 @@ return { short_desc=N_("program to use for the \":make\" command"), type='string', scope={'global', 'buffer'}, secure=true, - vi_def=true, expand=true, varname='p_mp', defaults={if_true={vi="make"}} @@ -1659,7 +1475,6 @@ return { short_desc=N_("pairs of characters that \"%\" can match"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, varname='p_mps', defaults={if_true={vi="(:),{:},[:]"}} @@ -1668,7 +1483,6 @@ return { full_name='matchtime', abbreviation='mat', short_desc=N_("tenths of a second to show matching paren"), type='number', scope={'global'}, - vi_def=true, varname='p_mat', defaults={if_true={vi=5}} }, @@ -1676,7 +1490,6 @@ return { full_name='maxcombine', abbreviation='mco', short_desc=N_("maximum nr of combining characters displayed"), type='number', scope={'global'}, - vi_def=true, varname='p_mco', defaults={if_true={vi=6}} }, @@ -1684,7 +1497,6 @@ return { full_name='maxfuncdepth', abbreviation='mfd', short_desc=N_("maximum recursive depth for user functions"), type='number', scope={'global'}, - vi_def=true, varname='p_mfd', defaults={if_true={vi=100}} }, @@ -1692,7 +1504,6 @@ return { full_name='maxmapdepth', abbreviation='mmd', short_desc=N_("maximum recursive depth for mapping"), type='number', scope={'global'}, - vi_def=true, varname='p_mmd', defaults={if_true={vi=1000}} }, @@ -1700,7 +1511,6 @@ return { full_name='maxmempattern', abbreviation='mmp', short_desc=N_("maximum memory (in Kbyte) used for pattern search"), type='number', scope={'global'}, - vi_def=true, varname='p_mmp', defaults={if_true={vi=1000}} }, @@ -1708,7 +1518,6 @@ return { full_name='menuitems', abbreviation='mis', short_desc=N_("maximum number of items in a menu"), type='number', scope={'global'}, - vi_def=true, varname='p_mis', defaults={if_true={vi=25}} }, @@ -1717,7 +1526,6 @@ return { short_desc=N_("memory used before |:mkspell| compresses the tree"), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_msm', defaults={if_true={vi="460000,2000,500"}} @@ -1726,15 +1534,13 @@ return { full_name='modeline', abbreviation='ml', short_desc=N_("recognize modelines at start or end of file"), type='bool', scope={'buffer'}, - vim=true, varname='p_ml', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='modelineexpr', abbreviation='mle', short_desc=N_("allow some options to be set in modeline"), type='bool', scope={'global'}, - vi_def=true, secure=true, varname='p_mle', defaults={if_true={vi=false}} @@ -1743,7 +1549,6 @@ return { full_name='modelines', abbreviation='mls', short_desc=N_("number of lines checked for modelines"), type='number', scope={'global'}, - vi_def=true, varname='p_mls', defaults={if_true={vi=5}} }, @@ -1752,7 +1557,6 @@ return { short_desc=N_("changes to the text are not possible"), type='bool', scope={'buffer'}, noglob=true, - vi_def=true, varname='p_ma', defaults={if_true={vi=true}} }, @@ -1761,7 +1565,6 @@ return { short_desc=N_("buffer has been modified"), type='bool', scope={'buffer'}, no_mkrc=true, - vi_def=true, redraw={'statuslines'}, varname='p_mod', defaults={if_true={vi=false}} @@ -1770,22 +1573,20 @@ return { full_name='more', short_desc=N_("listings when the whole screen is filled"), type='bool', scope={'global'}, - vim=true, varname='p_more', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='mouse', short_desc=N_("the use of mouse clicks"), type='string', list='flags', scope={'global'}, varname='p_mouse', - defaults={if_true={vi="", vim=""}} + defaults={if_true={vim=""}} }, { full_name='mousefocus', abbreviation='mousef', short_desc=N_("keyboard focus follows the mouse"), type='bool', scope={'global'}, - vi_def=true, redraw={'ui_option'}, varname='p_mousef', defaults={if_true={vi=false}} @@ -1794,7 +1595,6 @@ return { full_name='mousehide', abbreviation='mh', short_desc=N_("hide mouse pointer while typing"), type='bool', scope={'global'}, - vi_def=true, enable_if=false, defaults={if_true={vi=true}} }, @@ -1802,7 +1602,6 @@ return { full_name='mousemodel', abbreviation='mousem', short_desc=N_("changes meaning of mouse buttons"), type='string', scope={'global'}, - vi_def=true, varname='p_mousem', defaults={if_true={vi="extend"}} }, @@ -1811,14 +1610,12 @@ return { short_desc=N_("shape of the mouse pointer in different modes"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, enable_if=false, }, { full_name='mousetime', abbreviation='mouset', short_desc=N_("max time between mouse double-click"), type='number', scope={'global'}, - vi_def=true, varname='p_mouset', defaults={if_true={vi=500}} }, @@ -1829,13 +1626,12 @@ return { deny_duplicates=true, alloced=true, varname='p_nf', - defaults={if_true={vi="bin,octal,hex", vim="bin,hex"}} + defaults={if_true={vim="bin,hex"}} }, { full_name='number', abbreviation='nu', short_desc=N_("print the line number in front of each line"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -1843,16 +1639,14 @@ return { full_name='numberwidth', abbreviation='nuw', short_desc=N_("number of columns used for the line number"), type='number', scope={'window'}, - vim=true, redraw={'current_window'}, - defaults={if_true={vi=8, vim=4}} + defaults={if_true={vim=4}} }, { full_name='omnifunc', abbreviation='ofu', short_desc=N_("function for filetype-specific completion"), type='string', scope={'buffer'}, secure=true, - vi_def=true, alloced=true, varname='p_ofu', defaults={if_true={vi=""}} @@ -1861,16 +1655,14 @@ return { full_name='opendevice', abbreviation='odev', short_desc=N_("allow reading/writing devices on MS-Windows"), type='bool', scope={'global'}, - vi_def=true, enable_if=false, - defaults={if_true={vi=false, vim=false}} + defaults={if_true={vim=false}} }, { full_name='operatorfunc', abbreviation='opfunc', short_desc=N_("function to be called for |g@| operator"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_opfunc', defaults={if_true={vi=""}} }, @@ -1880,7 +1672,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, expand=true, varname='p_pp', defaults={if_true={vi=''}} @@ -1889,7 +1680,6 @@ return { full_name='paragraphs', abbreviation='para', short_desc=N_("nroff macros that separate paragraphs"), type='string', scope={'global'}, - vi_def=true, varname='p_para', defaults={if_true={vi="IPLPPPQPP TPHPLIPpLpItpplpipbp"}} }, @@ -1898,7 +1688,6 @@ return { short_desc=N_("pasting text"), type='bool', scope={'global'}, pri_mkrc=true, - vi_def=true, varname='p_paste', defaults={if_true={vi=false}} }, @@ -1906,7 +1695,6 @@ return { full_name='pastetoggle', abbreviation='pt', short_desc=N_("key code that causes 'paste' to toggle"), type='string', scope={'global'}, - vi_def=true, varname='p_pt', defaults={if_true={vi=""}} }, @@ -1915,7 +1703,6 @@ return { short_desc=N_("expression used to patch a file"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_pex', defaults={if_true={vi=""}} }, @@ -1924,7 +1711,6 @@ return { short_desc=N_("keep the oldest version of a file"), type='string', scope={'global'}, normal_fname_chars=true, - vi_def=true, varname='p_pm', defaults={if_true={vi=""}} }, @@ -1933,7 +1719,6 @@ return { short_desc=N_("list of directories searched with \"gf\" et.al."), type='string', list='comma', scope={'global', 'buffer'}, deny_duplicates=true, - vi_def=true, expand=true, varname='p_path', defaults={if_true={vi=".,/usr/include,,"}} @@ -1942,8 +1727,6 @@ return { full_name='preserveindent', abbreviation='pi', short_desc=N_("preserve the indent structure when reindenting"), type='bool', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_pi', defaults={if_true={vi=false}} }, @@ -1951,7 +1734,6 @@ return { full_name='previewheight', abbreviation='pvh', short_desc=N_("height of the preview window"), type='number', scope={'global'}, - vi_def=true, varname='p_pvh', defaults={if_true={vi=12}} }, @@ -1960,7 +1742,6 @@ return { short_desc=N_("identifies the preview window"), type='bool', scope={'window'}, noglob=true, - vi_def=true, redraw={'statuslines'}, defaults={if_true={vi=false}} }, @@ -1969,7 +1750,6 @@ return { short_desc=N_("name of the printer to be used for :hardcopy"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_pdev', defaults={if_true={vi=""}} }, @@ -1977,7 +1757,6 @@ return { full_name='printencoding', abbreviation='penc', short_desc=N_("encoding to be used for printing"), type='string', scope={'global'}, - vi_def=true, varname='p_penc', defaults={if_true={vi=""}} }, @@ -1986,7 +1765,6 @@ return { short_desc=N_("expression used to print PostScript for :hardcopy"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_pexpr', defaults={if_true={vi=""}} }, @@ -1994,7 +1772,6 @@ return { full_name='printfont', abbreviation='pfn', short_desc=N_("name of the font to be used for :hardcopy"), type='string', scope={'global'}, - vi_def=true, varname='p_pfn', defaults={if_true={vi="courier"}} }, @@ -2002,7 +1779,6 @@ return { full_name='printheader', abbreviation='pheader', short_desc=N_("format of the header used for :hardcopy"), type='string', scope={'global'}, - vi_def=true, varname='p_header', defaults={if_true={vi="%<%f%h%m%=Page %N"}} }, @@ -2010,7 +1786,6 @@ return { full_name='printmbcharset', abbreviation='pmbcs', short_desc=N_("CJK character set to be used for :hardcopy"), type='string', scope={'global'}, - vi_def=true, varname='p_pmcs', defaults={if_true={vi=""}} }, @@ -2018,7 +1793,6 @@ return { full_name='printmbfont', abbreviation='pmbfn', short_desc=N_("font names to be used for CJK output of :hardcopy"), type='string', scope={'global'}, - vi_def=true, varname='p_pmfn', defaults={if_true={vi=""}} }, @@ -2027,7 +1801,6 @@ return { short_desc=N_("controls the format of :hardcopy output"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_popt', defaults={if_true={vi=""}} }, @@ -2035,15 +1808,13 @@ return { full_name='prompt', short_desc=N_("enable prompt in Ex mode"), type='bool', scope={'global'}, - vi_def=true, - varname='p_prompt', + varname='p_force_on', defaults={if_true={vi=true}} }, { full_name='pumblend', abbreviation='pb', short_desc=N_("Controls transparency level of popup menu"), type='number', scope={'global'}, - vi_def=true, redraw={'ui_option'}, varname='p_pb', defaults={if_true={vi=0}} @@ -2052,7 +1823,6 @@ return { full_name='pumheight', abbreviation='ph', short_desc=N_("maximum height of the popup menu"), type='number', scope={'global'}, - vi_def=true, varname='p_ph', defaults={if_true={vi=0}} }, @@ -2060,7 +1830,6 @@ return { full_name='pumwidth', abbreviation='pw', short_desc=N_("minimum width of the popup menu"), type='number', scope={'global'}, - vi_def=true, varname='p_pw', defaults={if_true={vi=15}} }, @@ -2069,7 +1838,6 @@ return { short_desc=N_("selects default python version to use"), type='number', scope={'global'}, secure=true, - vi_def=true, varname='p_pyx', defaults={if_true={vi=0}} }, @@ -2077,7 +1845,6 @@ return { full_name='quickfixtextfunc', abbreviation='qftf', short_desc=N_("customize the quickfix window"), type='string', scope={'global'}, - vi_def=true, varname='p_qftf', defaults={if_true={vi=""}} }, @@ -2085,7 +1852,6 @@ return { full_name='quoteescape', abbreviation='qe', short_desc=N_("escape characters used in a string"), type='string', scope={'buffer'}, - vi_def=true, alloced=true, varname='p_qe', defaults={if_true={vi="\\"}} @@ -2095,7 +1861,6 @@ return { short_desc=N_("disallow writing the buffer"), type='bool', scope={'buffer'}, noglob=true, - vi_def=true, redraw={'statuslines'}, varname='p_ro', defaults={if_true={vi=false}} @@ -2104,7 +1869,6 @@ return { full_name='redrawdebug', abbreviation='rdb', short_desc=N_("Changes the way redrawing works (debug)"), type='string', list='onecomma', scope={'global'}, - vi_def=true, varname='p_rdb', defaults={if_true={vi=''}} }, @@ -2112,7 +1876,6 @@ return { full_name='redrawtime', abbreviation='rdt', short_desc=N_("timeout for 'hlsearch' and |:match| highlighting"), type='number', scope={'global'}, - vi_def=true, varname='p_rdt', defaults={if_true={vi=2000}} }, @@ -2120,7 +1883,6 @@ return { full_name='regexpengine', abbreviation='re', short_desc=N_("default regexp engine to use"), type='number', scope={'global'}, - vi_def=true, varname='p_re', defaults={if_true={vi=0}} }, @@ -2128,7 +1890,6 @@ return { full_name='relativenumber', abbreviation='rnu', short_desc=N_("show relative line number in front of each line"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -2136,7 +1897,6 @@ return { full_name='remap', short_desc=N_("mappings to work recursively"), type='bool', scope={'global'}, - vi_def=true, varname='p_remap', defaults={if_true={vi=true}} }, @@ -2144,7 +1904,6 @@ return { full_name='report', short_desc=N_("for reporting nr. of lines changed"), type='number', scope={'global'}, - vi_def=true, varname='p_report', defaults={if_true={vi=2}} }, @@ -2152,8 +1911,6 @@ return { full_name='revins', abbreviation='ri', short_desc=N_("inserting characters will work backwards"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_ri', defaults={if_true={vi=false}} }, @@ -2161,7 +1918,6 @@ return { full_name='rightleft', abbreviation='rl', short_desc=N_("window is right-to-left oriented"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -2169,7 +1925,6 @@ return { full_name='rightleftcmd', abbreviation='rlc', short_desc=N_("commands for which editing works right-to-left"), type='string', scope={'window'}, - vi_def=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi="search"}} @@ -2178,8 +1933,6 @@ return { full_name='ruler', abbreviation='ru', short_desc=N_("show cursor line and column in the status line"), type='bool', scope={'global'}, - vi_def=true, - vim=true, redraw={'statuslines'}, varname='p_ru', defaults={if_true={vi=true}} @@ -2188,7 +1941,6 @@ return { full_name='rulerformat', abbreviation='ruf', short_desc=N_("custom format for the ruler"), type='string', scope={'global'}, - vi_def=true, alloced=true, modelineexpr=true, redraw={'statuslines'}, @@ -2201,7 +1953,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, expand='nodefault', varname='p_rtp', defaults={if_true={vi=''}} @@ -2211,7 +1962,6 @@ return { short_desc=N_("lines to scroll with CTRL-U and CTRL-D"), type='number', scope={'window'}, no_mkrc=true, - vi_def=true, pv_name='p_scroll', defaults={if_true={vi=0}} }, @@ -2219,7 +1969,6 @@ return { full_name='scrollback', abbreviation='scbk', short_desc=N_("lines to scroll with CTRL-U and CTRL-D"), type='number', scope={'buffer'}, - vi_def=true, varname='p_scbk', redraw={'current_buffer'}, defaults={if_true={vi=-1}} @@ -2228,7 +1977,6 @@ return { full_name='scrollbind', abbreviation='scb', short_desc=N_("scroll in window as other windows scroll"), type='bool', scope={'window'}, - vi_def=true, pv_name='p_scbind', defaults={if_true={vi=false}} }, @@ -2236,8 +1984,6 @@ return { full_name='scrolljump', abbreviation='sj', short_desc=N_("minimum number of lines to scroll"), type='number', scope={'global'}, - vi_def=true, - vim=true, varname='p_sj', defaults={if_true={vi=1}} }, @@ -2245,8 +1991,6 @@ return { full_name='scrolloff', abbreviation='so', short_desc=N_("minimum nr. of lines above and below cursor"), type='number', scope={'global', 'window'}, - vi_def=true, - vim=true, redraw={'all_windows'}, varname='p_so', defaults={if_true={vi=0}} @@ -2256,7 +2000,6 @@ return { short_desc=N_("how 'scrollbind' should behave"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_sbo', defaults={if_true={vi="ver,jump"}} }, @@ -2264,7 +2007,6 @@ return { full_name='sections', abbreviation='sect', short_desc=N_("nroff macros that separate sections"), type='string', scope={'global'}, - vi_def=true, varname='p_sections', defaults={if_true={vi="SHNHH HUnhsh"}} }, @@ -2273,7 +2015,6 @@ return { short_desc=N_("mode for reading .vimrc in current dir"), type='bool', scope={'global'}, secure=true, - vi_def=true, varname='p_secure', defaults={if_true={vi=false}} }, @@ -2281,7 +2022,6 @@ return { full_name='selection', abbreviation='sel', short_desc=N_("what type of selection to use"), type='string', scope={'global'}, - vi_def=true, varname='p_sel', defaults={if_true={vi="inclusive"}} }, @@ -2290,7 +2030,6 @@ return { short_desc=N_("when to use Select mode instead of Visual mode"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_slm', defaults={if_true={vi=""}} }, @@ -2299,10 +2038,8 @@ return { short_desc=N_("options for |:mksession|"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vim=true, varname='p_ssop', defaults={if_true={ - vi="blank,buffers,curdir,folds,help,options,tabpages,winsize", vim="blank,buffers,curdir,folds,help,tabpages,winsize" }} }, @@ -2313,14 +2050,13 @@ return { deny_duplicates=true, secure=true, varname='p_shada', - defaults={if_true={vi="", vim="!,'100,<50,s10,h"}} + defaults={if_true={vim="!,'100,<50,s10,h"}} }, { full_name='shadafile', abbreviation='sdf', short_desc=N_("overrides the filename used for shada"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, secure=true, expand=true, varname='p_shadafile', @@ -2331,7 +2067,6 @@ return { short_desc=N_("name of shell to use for external commands"), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_sh', defaults={ @@ -2345,7 +2080,6 @@ return { short_desc=N_("flag to shell to execute one command"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_shcf', defaults={ condition='WIN32', @@ -2358,7 +2092,6 @@ return { short_desc=N_("string to put output of \":make\" in error file"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_sp', defaults={ condition='WIN32', @@ -2371,7 +2104,6 @@ return { short_desc=N_("quote character(s) for around shell command"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_shq', defaults={if_true={vi=""}} }, @@ -2380,7 +2112,6 @@ return { short_desc=N_("string to put output of filter in a temp file"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_srr', defaults={ condition='WIN32', @@ -2392,7 +2123,6 @@ return { full_name='shellslash', abbreviation='ssl', short_desc=N_("use forward slash for shell file names"), type='bool', scope={'global'}, - vi_def=true, varname='p_ssl', enable_if='BACKSLASH_IN_FILENAME', defaults={if_true={vi=false}} @@ -2402,14 +2132,13 @@ return { short_desc=N_("whether to use a temp file for shell commands"), type='bool', scope={'global'}, varname='p_stmp', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='shellxquote', abbreviation='sxq', short_desc=N_("like 'shellquote', but include redirection"), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_sxq', defaults={ condition='WIN32', @@ -2422,7 +2151,6 @@ return { short_desc=N_("characters to escape when 'shellxquote' is ("), type='string', scope={'global'}, secure=true, - vi_def=true, varname='p_sxe', defaults={if_true={vi=""}} }, @@ -2430,8 +2158,6 @@ return { full_name='shiftround', abbreviation='sr', short_desc=N_("round indent to multiple of shiftwidth"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_sr', defaults={if_true={vi=false}} }, @@ -2439,7 +2165,6 @@ return { full_name='shiftwidth', abbreviation='sw', short_desc=N_("number of spaces to use for (auto)indent step"), type='number', scope={'buffer'}, - vi_def=true, varname='p_sw', defaults={if_true={vi=8}} }, @@ -2447,15 +2172,13 @@ return { full_name='shortmess', abbreviation='shm', short_desc=N_("list of flags, reduce length of messages"), type='string', list='flags', scope={'global'}, - vim=true, varname='p_shm', - defaults={if_true={vi="S", vim="filnxtToOF"}} + defaults={if_true={vim="filnxtToOF"}} }, { full_name='showbreak', abbreviation='sbr', short_desc=N_("string to use at the start of wrapped lines"), type='string', scope={'global'}, - vi_def=true, redraw={'all_windows'}, varname='p_sbr', defaults={if_true={vi=""}} @@ -2464,15 +2187,13 @@ return { full_name='showcmd', abbreviation='sc', short_desc=N_("show (partial) command in status line"), type='bool', scope={'global'}, - vim=true, varname='p_sc', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='showfulltag', abbreviation='sft', short_desc=N_("show full tag pattern when completing tag"), type='bool', scope={'global'}, - vi_def=true, varname='p_sft', defaults={if_true={vi=false}} }, @@ -2480,7 +2201,6 @@ return { full_name='showmatch', abbreviation='sm', short_desc=N_("briefly jump to matching bracket if insert one"), type='bool', scope={'global'}, - vi_def=true, varname='p_sm', defaults={if_true={vi=false}} }, @@ -2488,15 +2208,13 @@ return { full_name='showmode', abbreviation='smd', short_desc=N_("message on status line to show current mode"), type='bool', scope={'global'}, - vim=true, varname='p_smd', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='showtabline', abbreviation='stal', short_desc=N_("tells when the tab pages line is displayed"), type='number', scope={'global'}, - vi_def=true, redraw={'all_windows', 'ui_option'}, varname='p_stal', defaults={if_true={vi=1}} @@ -2505,7 +2223,6 @@ return { full_name='sidescroll', abbreviation='ss', short_desc=N_("minimum number of columns to scroll horizontal"), type='number', scope={'global'}, - vi_def=true, varname='p_ss', defaults={if_true={vi=1}} }, @@ -2513,8 +2230,6 @@ return { full_name='sidescrolloff', abbreviation='siso', short_desc=N_("min. nr. of columns to left and right of cursor"), type='number', scope={'global', 'window'}, - vi_def=true, - vim=true, redraw={'all_windows'}, varname='p_siso', defaults={if_true={vi=0}} @@ -2523,7 +2238,6 @@ return { full_name='signcolumn', abbreviation='scl', short_desc=N_("when to display the sign column"), type='string', scope={'window'}, - vi_def=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi="auto"}} @@ -2532,8 +2246,6 @@ return { full_name='smartcase', abbreviation='scs', short_desc=N_("no ignore case when pattern has uppercase"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_scs', defaults={if_true={vi=false}} }, @@ -2541,8 +2253,6 @@ return { full_name='smartindent', abbreviation='si', short_desc=N_("smart autoindenting for C programs"), type='bool', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_si', defaults={if_true={vi=false}} }, @@ -2550,16 +2260,13 @@ return { full_name='smarttab', abbreviation='sta', short_desc=N_("use 'shiftwidth' when inserting <Tab>"), type='bool', scope={'global'}, - vim=true, varname='p_sta', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='softtabstop', abbreviation='sts', short_desc=N_("number of spaces that <Tab> uses while editing"), type='number', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_sts', defaults={if_true={vi=0}} }, @@ -2567,7 +2274,6 @@ return { full_name='spell', short_desc=N_("spell checking"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=false}} }, @@ -2575,7 +2281,6 @@ return { full_name='spellcapcheck', abbreviation='spc', short_desc=N_("pattern to locate end of a sentence"), type='string', scope={'buffer'}, - vi_def=true, alloced=true, redraw={'current_buffer'}, varname='p_spc', @@ -2587,7 +2292,6 @@ return { type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, secure=true, - vi_def=true, alloced=true, expand=true, varname='p_spf', @@ -2598,7 +2302,6 @@ return { short_desc=N_("language(s) to do spell checking for"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, expand=true, redraw={'current_buffer'}, @@ -2611,7 +2314,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, expand=true, varname='p_sps', defaults={if_true={vi="best"}} @@ -2621,16 +2323,14 @@ return { type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, secure=true, - vi_def=true, expand=true, varname='p_spo', - defaults={if_true={vi="", vim=""}} + defaults={if_true={vim=""}} }, { full_name='splitbelow', abbreviation='sb', short_desc=N_("new window from split is below the current one"), type='bool', scope={'global'}, - vi_def=true, varname='p_sb', defaults={if_true={vi=false}} }, @@ -2638,7 +2338,6 @@ return { full_name='splitright', abbreviation='spr', short_desc=N_("new window is put right of the current one"), type='bool', scope={'global'}, - vi_def=true, varname='p_spr', defaults={if_true={vi=false}} }, @@ -2646,7 +2345,6 @@ return { full_name='startofline', abbreviation='sol', short_desc=N_("commands move cursor to first non-blank in line"), type='bool', scope={'global'}, - vi_def=true, vim=false, varname='p_sol', defaults={if_true={vi=false}} @@ -2655,7 +2353,6 @@ return { full_name='statusline', abbreviation='stl', short_desc=N_("custom format for the status line"), type='string', scope={'global', 'window'}, - vi_def=true, alloced=true, modelineexpr=true, redraw={'statuslines'}, @@ -2667,7 +2364,6 @@ return { short_desc=N_("suffixes that are ignored with multiple match"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_su', defaults={if_true={vi=".bak,~,.o,.h,.info,.swp,.obj"}} }, @@ -2676,7 +2372,6 @@ return { short_desc=N_("suffixes added when searching for a file"), type='string', list='onecomma', scope={'buffer'}, deny_duplicates=true, - vi_def=true, alloced=true, varname='p_sua', defaults={if_true={vi=""}} @@ -2685,7 +2380,6 @@ return { full_name='swapfile', abbreviation='swf', short_desc=N_("whether to use a swapfile for a buffer"), type='bool', scope={'buffer'}, - vi_def=true, redraw={'statuslines'}, varname='p_swf', defaults={if_true={vi=true}} @@ -2695,7 +2389,6 @@ return { short_desc=N_("sets behavior when switching to another buffer"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_swb', defaults={if_true={vi=""}} }, @@ -2703,7 +2396,6 @@ return { full_name='synmaxcol', abbreviation='smc', short_desc=N_("maximum column to find syntax items"), type='number', scope={'buffer'}, - vi_def=true, redraw={'current_buffer'}, varname='p_smc', defaults={if_true={vi=3000}} @@ -2714,7 +2406,6 @@ return { type='string', scope={'buffer'}, noglob=true, normal_fname_chars=true, - vi_def=true, alloced=true, varname='p_syn', defaults={if_true={vi=""}} @@ -2723,8 +2414,6 @@ return { full_name='tagfunc', abbreviation='tfu', short_desc=N_("function used to perform tag searches"), type='string', scope={'buffer'}, - vim=true, - vi_def=true, varname='p_tfu', defaults={if_true={vi=""}} }, @@ -2732,7 +2421,6 @@ return { full_name='tabline', abbreviation='tal', short_desc=N_("custom format for the console tab pages line"), type='string', scope={'global'}, - vi_def=true, modelineexpr=true, redraw={'all_windows'}, varname='p_tal', @@ -2742,15 +2430,13 @@ return { full_name='tabpagemax', abbreviation='tpm', short_desc=N_("maximum number of tab pages for |-p| and \"tab all\""), type='number', scope={'global'}, - vim=true, varname='p_tpm', - defaults={if_true={vi=10, vim=50}} + defaults={if_true={vim=50}} }, { full_name='tabstop', abbreviation='ts', short_desc=N_("number of spaces that <Tab> in file uses"), type='number', scope={'buffer'}, - vi_def=true, redraw={'current_buffer'}, varname='p_ts', defaults={if_true={vi=8}} @@ -2759,7 +2445,6 @@ return { full_name='tagbsearch', abbreviation='tbs', short_desc=N_("use binary searching in tags files"), type='bool', scope={'global'}, - vi_def=true, varname='p_tbs', defaults={if_true={vi=true}} }, @@ -2767,15 +2452,13 @@ return { full_name='tagcase', abbreviation='tc', short_desc=N_("how to handle case when searching in tags files"), type='string', scope={'global', 'buffer'}, - vim=true, varname='p_tc', - defaults={if_true={vi="followic", vim="followic"}} + defaults={if_true={vim="followic"}} }, { full_name='taglength', abbreviation='tl', short_desc=N_("number of significant characters for a tag"), type='number', scope={'global'}, - vi_def=true, varname='p_tl', defaults={if_true={vi=0}} }, @@ -2783,16 +2466,14 @@ return { full_name='tagrelative', abbreviation='tr', short_desc=N_("file names in tag file are relative"), type='bool', scope={'global'}, - vim=true, varname='p_tr', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='tags', abbreviation='tag', short_desc=N_("list of file names used by the tag command"), type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, - vi_def=true, expand=true, varname='p_tags', defaults={if_true={vi="./tags;,tags"}} @@ -2801,7 +2482,6 @@ return { full_name='tagstack', abbreviation='tgst', short_desc=N_("push tags onto the tag stack"), type='bool', scope={'global'}, - vi_def=true, varname='p_tgst', defaults={if_true={vi=true}} }, @@ -2809,7 +2489,6 @@ return { full_name='termbidi', abbreviation='tbidi', short_desc=N_("terminal takes care of bi-directionality"), type='bool', scope={'global'}, - vi_def=true, varname='p_tbidi', defaults={if_true={vi=false}} }, @@ -2817,14 +2496,12 @@ return { full_name='termencoding', abbreviation='tenc', short_desc=N_("Terminal encodig"), type='string', scope={'global'}, - vi_def=true, defaults={if_true={vi=""}} }, { full_name='termguicolors', abbreviation='tgc', short_desc=N_("Terminal true color support"), type='bool', scope={'global'}, - vi_def=false, redraw={'ui_option'}, varname='p_tgc', defaults={if_true={vi=false}} @@ -2833,15 +2510,13 @@ return { full_name='termpastefilter', abbreviation='tpf', type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vim=true, varname='p_tpf', - defaults={if_true={vi="", vim="BS,HT,ESC,DEL"}} + defaults={if_true={vim="BS,HT,ESC,DEL"}} }, { full_name='terse', short_desc=N_("hides notification of search wrap"), type='bool', scope={'global'}, - vi_def=true, varname='p_terse', defaults={if_true={vi=false}} }, @@ -2849,8 +2524,6 @@ return { full_name='textwidth', abbreviation='tw', short_desc=N_("maximum width of text that is being inserted"), type='number', scope={'buffer'}, - vi_def=true, - vim=true, redraw={'current_buffer'}, varname='p_tw', defaults={if_true={vi=0}} @@ -2861,7 +2534,6 @@ return { type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, normal_dname_chars=true, - vi_def=true, expand=true, varname='p_tsr', defaults={if_true={vi=""}} @@ -2870,8 +2542,6 @@ return { full_name='tildeop', abbreviation='top', short_desc=N_("tilde command \"~\" behaves like an operator"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_to', defaults={if_true={vi=false}} }, @@ -2879,7 +2549,6 @@ return { full_name='timeout', abbreviation='to', short_desc=N_("time out on mappings and key codes"), type='bool', scope={'global'}, - vi_def=true, varname='p_timeout', defaults={if_true={vi=true}} }, @@ -2887,7 +2556,6 @@ return { full_name='timeoutlen', abbreviation='tm', short_desc=N_("time out time in milliseconds"), type='number', scope={'global'}, - vi_def=true, varname='p_tm', defaults={if_true={vi=1000}} }, @@ -2895,7 +2563,6 @@ return { full_name='title', short_desc=N_("Vim set the title of the window"), type='bool', scope={'global'}, - vi_def=true, varname='p_title', defaults={if_true={vi=false}} }, @@ -2903,7 +2570,6 @@ return { full_name='titlelen', short_desc=N_("of 'columns' used for window title"), type='number', scope={'global'}, - vi_def=true, varname='p_titlelen', defaults={if_true={vi=85}} }, @@ -2913,7 +2579,6 @@ return { type='string', scope={'global'}, secure=true, no_mkrc=true, - vi_def=true, varname='p_titleold', defaults={if_true={vi=""}} }, @@ -2921,7 +2586,6 @@ return { full_name='titlestring', short_desc=N_("to use for the Vim window title"), type='string', scope={'global'}, - vi_def=true, modelineexpr=true, varname='p_titlestring', defaults={if_true={vi=""}} @@ -2930,8 +2594,6 @@ return { full_name='ttimeout', short_desc=N_("out on mappings"), type='bool', scope={'global'}, - vi_def=true, - vim=true, redraw={'ui_option'}, varname='p_ttimeout', defaults={if_true={vi=true}} @@ -2940,7 +2602,6 @@ return { full_name='ttimeoutlen', abbreviation='ttm', short_desc=N_("time out time for key codes in milliseconds"), type='number', scope={'global'}, - vi_def=true, redraw={'ui_option'}, varname='p_ttm', defaults={if_true={vi=50}} @@ -2950,7 +2611,6 @@ return { short_desc=N_("No description"), type='bool', scope={'global'}, no_mkrc=true, - vi_def=true, varname='p_force_on', defaults={if_true={vi=true}} }, @@ -2960,7 +2620,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, secure=true, - vi_def=true, expand='nodefault', varname='p_udir', defaults={if_true={vi=''}} @@ -2969,8 +2628,6 @@ return { full_name='undofile', abbreviation='udf', short_desc=N_("save undo information in a file"), type='bool', scope={'buffer'}, - vi_def=true, - vim=true, varname='p_udf', defaults={if_true={vi=false}} }, @@ -2978,7 +2635,6 @@ return { full_name='undolevels', abbreviation='ul', short_desc=N_("maximum number of changes that can be undone"), type='number', scope={'global', 'buffer'}, - vi_def=true, varname='p_ul', defaults={if_true={vi=1000}} }, @@ -2986,7 +2642,6 @@ return { full_name='undoreload', abbreviation='ur', short_desc=N_("max nr of lines to save for undo on a buffer reload"), type='number', scope={'global'}, - vi_def=true, varname='p_ur', defaults={if_true={vi=10000}} }, @@ -2994,7 +2649,6 @@ return { full_name='updatecount', abbreviation='uc', short_desc=N_("after this many characters flush swap file"), type='number', scope={'global'}, - vi_def=true, varname='p_uc', defaults={if_true={vi=200}} }, @@ -3002,7 +2656,6 @@ return { full_name='updatetime', abbreviation='ut', short_desc=N_("after this many milliseconds flush swap file"), type='number', scope={'global'}, - vi_def=true, varname='p_ut', defaults={if_true={vi=4000}} }, @@ -3010,7 +2663,6 @@ return { full_name='varsofttabstop', abbreviation='vsts', short_desc=N_("list of numbers of spaces that <Tab> uses while editing"), type='string', list='comma', scope={'buffer'}, - vi_def=true, varname='p_vsts', defaults={if_true={vi=""}} }, @@ -3018,7 +2670,6 @@ return { full_name='vartabstop', abbreviation='vts', short_desc=N_("list of numbers of spaces that <Tab> in file uses"), type='string', list='comma', scope={'buffer'}, - vi_def=true, varname='p_vts', redraw={'current_buffer'}, defaults={if_true={vi=""}} @@ -3027,7 +2678,6 @@ return { full_name='verbose', abbreviation='vbs', short_desc=N_("give informative messages"), type='number', scope={'global'}, - vi_def=true, varname='p_verbose', defaults={if_true={vi=0}} }, @@ -3036,7 +2686,6 @@ return { short_desc=N_("file to write messages in"), type='string', scope={'global'}, secure=true, - vi_def=true, expand=true, varname='p_vfile', defaults={if_true={vi=""}} @@ -3046,7 +2695,6 @@ return { short_desc=N_("directory where to store files with :mkview"), type='string', scope={'global'}, secure=true, - vi_def=true, expand='nodefault', varname='p_vdir', defaults={if_true={vi=''}} @@ -3056,7 +2704,6 @@ return { short_desc=N_("specifies what to save for :mkview"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_vop', defaults={if_true={vi="folds,options,cursor,curdir"}} }, @@ -3077,17 +2724,14 @@ return { short_desc=N_("when to use virtual editing"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, - vim=true, redraw={'curswant'}, varname='p_ve', - defaults={if_true={vi="", vim=""}} + defaults={if_true={vim=""}} }, { full_name='visualbell', abbreviation='vb', short_desc=N_("use visual bell instead of beeping"), type='bool', scope={'global'}, - vi_def=true, varname='p_vb', defaults={if_true={vi=false}} }, @@ -3095,7 +2739,6 @@ return { full_name='warn', short_desc=N_("for shell command when buffer was changed"), type='bool', scope={'global'}, - vi_def=true, varname='p_warn', defaults={if_true={vi=true}} }, @@ -3103,23 +2746,20 @@ return { full_name='whichwrap', abbreviation='ww', short_desc=N_("allow specified keys to cross line boundaries"), type='string', list='flagscomma', scope={'global'}, - vim=true, varname='p_ww', - defaults={if_true={vi="", vim="b,s"}} + defaults={if_true={vim="b,s"}} }, { full_name='wildchar', abbreviation='wc', short_desc=N_("command-line character for wildcard expansion"), type='number', scope={'global'}, - vim=true, varname='p_wc', - defaults={if_true={vi=imacros('Ctrl_E'), vim=imacros('TAB')}} + defaults={if_true={vim=imacros('TAB')}} }, { full_name='wildcharm', abbreviation='wcm', short_desc=N_("like 'wildchar' but also works when mapped"), type='number', scope={'global'}, - vi_def=true, varname='p_wcm', defaults={if_true={vi=0}} }, @@ -3128,7 +2768,6 @@ return { short_desc=N_("files matching these patterns are not completed"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vi_def=true, varname='p_wig', defaults={if_true={vi=""}} }, @@ -3136,7 +2775,6 @@ return { full_name='wildignorecase', abbreviation='wic', short_desc=N_("ignore case when completing file names"), type='bool', scope={'global'}, - vi_def=true, varname='p_wic', defaults={if_true={vi=false}} }, @@ -3144,33 +2782,29 @@ return { full_name='wildmenu', abbreviation='wmnu', short_desc=N_("use menu for command line completion"), type='bool', scope={'global'}, - vim=true, varname='p_wmnu', - defaults={if_true={vi=false, vim=true}} + defaults={if_true={vim=true}} }, { full_name='wildmode', abbreviation='wim', short_desc=N_("mode for 'wildchar' command-line expansion"), type='string', list='onecomma', scope={'global'}, deny_duplicates=false, - vim=true, varname='p_wim', - defaults={if_true={vi="", vim="full"}} + defaults={if_true={vim="full"}} }, { full_name='wildoptions', abbreviation='wop', short_desc=N_("specifies how command line completion is done"), type='string', list='onecomma', scope={'global'}, deny_duplicates=true, - vim=true, varname='p_wop', - defaults={if_true={vi='', vim='pum,tagfile'}} + defaults={if_true={vim='pum,tagfile'}} }, { full_name='winaltkeys', abbreviation='wak', short_desc=N_("when the windows system handles ALT keys"), type='string', scope={'global'}, - vi_def=true, varname='p_wak', defaults={if_true={vi="menu"}} }, @@ -3178,7 +2812,6 @@ return { full_name='winblend', abbreviation='winbl', short_desc=N_("Controls transparency level for floating windows"), type='number', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=0}} }, @@ -3186,7 +2819,6 @@ return { full_name='winhighlight', abbreviation='winhl', short_desc=N_("Setup window-local highlights"); type='string', scope={'window'}, - vi_def=true, alloced=true, redraw={'current_window'}, defaults={if_true={vi=""}} @@ -3195,7 +2827,6 @@ return { full_name='window', abbreviation='wi', short_desc=N_("nr of lines to scroll for CTRL-F and CTRL-B"), type='number', scope={'global'}, - vi_def=true, varname='p_window', defaults={if_true={vi=0}} }, @@ -3203,7 +2834,6 @@ return { full_name='winheight', abbreviation='wh', short_desc=N_("minimum number of lines for the current window"), type='number', scope={'global'}, - vi_def=true, varname='p_wh', defaults={if_true={vi=1}} }, @@ -3211,7 +2841,6 @@ return { full_name='winfixheight', abbreviation='wfh', short_desc=N_("keep window height when opening/closing windows"), type='bool', scope={'window'}, - vi_def=true, redraw={'statuslines'}, defaults={if_true={vi=false}} }, @@ -3219,7 +2848,6 @@ return { full_name='winfixwidth', abbreviation='wfw', short_desc=N_("keep window width when opening/closing windows"), type='bool', scope={'window'}, - vi_def=true, redraw={'statuslines'}, defaults={if_true={vi=false}} }, @@ -3227,7 +2855,6 @@ return { full_name='winminheight', abbreviation='wmh', short_desc=N_("minimum number of lines for any window"), type='number', scope={'global'}, - vi_def=true, varname='p_wmh', defaults={if_true={vi=1}} }, @@ -3235,7 +2862,6 @@ return { full_name='winminwidth', abbreviation='wmw', short_desc=N_("minimal number of columns for any window"), type='number', scope={'global'}, - vi_def=true, varname='p_wmw', defaults={if_true={vi=1}} }, @@ -3243,7 +2869,6 @@ return { full_name='winwidth', abbreviation='wiw', short_desc=N_("minimal number of columns for current window"), type='number', scope={'global'}, - vi_def=true, varname='p_wiw', defaults={if_true={vi=20}} }, @@ -3251,7 +2876,6 @@ return { full_name='wrap', short_desc=N_("lines wrap and continue on the next line"), type='bool', scope={'window'}, - vi_def=true, redraw={'current_window'}, defaults={if_true={vi=true}} }, @@ -3259,7 +2883,6 @@ return { full_name='wrapmargin', abbreviation='wm', short_desc=N_("chars from the right where wrapping starts"), type='number', scope={'buffer'}, - vi_def=true, varname='p_wm', defaults={if_true={vi=0}} }, @@ -3267,7 +2890,6 @@ return { full_name='wrapscan', abbreviation='ws', short_desc=N_("searches wrap around the end of the file"), type='bool', scope={'global'}, - vi_def=true, varname='p_ws', defaults={if_true={vi=true}} }, @@ -3275,7 +2897,6 @@ return { full_name='write', short_desc=N_("to a file is allowed"), type='bool', scope={'global'}, - vi_def=true, varname='p_write', defaults={if_true={vi=true}} }, @@ -3283,7 +2904,6 @@ return { full_name='writeany', abbreviation='wa', short_desc=N_("write to file with no need for \"!\" override"), type='bool', scope={'global'}, - vi_def=true, varname='p_wa', defaults={if_true={vi=false}} }, @@ -3291,8 +2911,6 @@ return { full_name='writebackup', abbreviation='wb', short_desc=N_("make a backup before overwriting a file"), type='bool', scope={'global'}, - vi_def=true, - vim=true, varname='p_wb', defaults={if_true={vi=true}} }, @@ -3300,7 +2918,6 @@ return { full_name='writedelay', abbreviation='wd', short_desc=N_("delay this many msec for each char (for debug)"), type='number', scope={'global'}, - vi_def=true, varname='p_wd', defaults={if_true={vi=0}} }, diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index bb68326a03..fa359fa32e 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -4,7 +4,7 @@ /// @file fileio.c /// /// Buffered reading/writing to a file. Unlike fileio.c this is not dealing with -/// Nvim stuctures for buffer, with autocommands, etc: just fopen/fread/fwrite +/// Nvim structures for buffer, with autocommands, etc: just fopen/fread/fwrite /// replacement. #include <assert.h> diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index d0fa74a77f..b8ba2487f3 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1119,7 +1119,7 @@ uint64_t os_fileinfo_blocksize(const FileInfo *file_info) /// /// @param path Path to the file. /// @param[out] file_info Pointer to a `FileID` to fill in. -/// @return `true` on sucess, `false` for failure. +/// @return `true` on success, `false` for failure. bool os_fileid(const char *path, FileID *file_id) FUNC_ATTR_NONNULL_ALL { diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c index 5bcadd6490..775e303f84 100644 --- a/src/nvim/os/pty_conpty_win.c +++ b/src/nvim/os/pty_conpty_win.c @@ -104,7 +104,7 @@ conpty_t *os_conpty_init(char **in_name, char **out_name, HRESULT hr; hr = pCreatePseudoConsole(size, in_read, out_write, 0, &conpty_object->pty); if (FAILED(hr)) { - emsg = "create psudo console failed"; + emsg = "create pseudo console failed"; goto failed; } diff --git a/src/nvim/path.c b/src/nvim/path.c index 6ac24182cc..e8d5cd9102 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -383,7 +383,7 @@ int path_fnamencmp(const char *const fname1, const char *const fname2, /// /// @param[in] fname1 First fname to append to. /// @param[in] len1 Length of fname1. -/// @param[in] fname2 Secord part of the file name. +/// @param[in] fname2 Second part of the file name. /// @param[in] len2 Length of fname2. /// @param[in] sep If true and fname1 does not end with a path separator, /// add a path separator before fname2. diff --git a/src/nvim/plines.c b/src/nvim/plines.c new file mode 100644 index 0000000000..6718b7f7a4 --- /dev/null +++ b/src/nvim/plines.c @@ -0,0 +1,481 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +// plines.c: calculate the vertical and horizontal size of text in a window + +#include <assert.h> +#include <inttypes.h> +#include <stdbool.h> +#include <string.h> +#include <limits.h> + +#include "nvim/vim.h" +#include "nvim/ascii.h" +#include "nvim/plines.h" +#include "nvim/charset.h" +#include "nvim/cursor.h" +#include "nvim/diff.h" +#include "nvim/func_attr.h" +#include "nvim/fold.h" +#include "nvim/indent.h" +#include "nvim/main.h" +#include "nvim/mbyte.h" +#include "nvim/memline.h" +#include "nvim/memory.h" +#include "nvim/move.h" +#include "nvim/option.h" +#include "nvim/screen.h" +#include "nvim/strings.h" +#include "nvim/window.h" +#include "nvim/buffer.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "plines.c.generated.h" +#endif + +/// Functions calculating vertical size of text when displayed inside a window. +/// Calls horizontal size functions defined below. + +/// @param winheight when true limit to window height +int plines_win(win_T *wp, linenr_T lnum, bool winheight) +{ + // Check for filler lines above this buffer line. When folded the result + // is one line anyway. + return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum); +} + +/// @param winheight when true limit to window height +int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight) +{ + if (!wp->w_p_wrap) { + return 1; + } + + if (wp->w_width_inner == 0) { + return 1; + } + + // A folded lines is handled just like an empty line. + if (lineFolded(wp, lnum)) { + return 1; + } + + const int lines = plines_win_nofold(wp, lnum); + if (winheight && lines > wp->w_height_inner) { + return wp->w_height_inner; + } + return lines; +} + +/// @Return number of window lines physical line "lnum" will occupy in window +/// "wp". Does not care about folding, 'wrap' or 'diff'. +int plines_win_nofold(win_T *wp, linenr_T lnum) +{ + char_u *s; + unsigned int col; + int width; + + s = ml_get_buf(wp->w_buffer, lnum, false); + if (*s == NUL) { // empty line + return 1; + } + col = win_linetabsize(wp, s, MAXCOL); + + // If list mode is on, then the '$' at the end of the line may take up one + // extra column. + if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) { + col += 1; + } + + // Add column offset for 'number', 'relativenumber' and 'foldcolumn'. + width = wp->w_width_inner - win_col_off(wp); + if (width <= 0 || col > 32000) { + return 32000; // bigger than the number of screen columns + } + if (col <= (unsigned int)width) { + return 1; + } + col -= (unsigned int)width; + width += win_col_off2(wp); + assert(col <= INT_MAX && (int)col < INT_MAX - (width -1)); + return ((int)col + (width - 1)) / width + 1; +} + +/// Like plines_win(), but only reports the number of physical screen lines +/// used from the start of the line to the given column number. +int plines_win_col(win_T *wp, linenr_T lnum, long column) +{ + // Check for filler lines above this buffer line. When folded the result + // is one line anyway. + int lines = diff_check_fill(wp, lnum); + + if (!wp->w_p_wrap) { + return lines + 1; + } + + if (wp->w_width_inner == 0) { + return lines + 1; + } + + char_u *line = ml_get_buf(wp->w_buffer, lnum, false); + char_u *s = line; + + colnr_T col = 0; + while (*s != NUL && --column >= 0) { + col += win_lbr_chartabsize(wp, line, s, col, NULL); + MB_PTR_ADV(s); + } + + // If *s is a TAB, and the TAB is not displayed as ^I, and we're not in + // INSERT mode, then col must be adjusted so that it represents the last + // screen position of the TAB. This only fixes an error when the TAB wraps + // from one screen line to the next (when 'columns' is not a multiple of + // 'ts') -- webb. + if (*s == TAB && (State & NORMAL) + && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { + col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1; + } + + // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. + int width = wp->w_width_inner - win_col_off(wp); + if (width <= 0) { + return 9999; + } + + lines += 1; + if (col > width) { + lines += (col - width) / (width + win_col_off2(wp)) + 1; + } + return lines; +} + +/// Get the number of screen lines lnum takes up. This takes care of +/// both folds and topfill, and limits to the current window height. +/// +/// @param[in] wp window line is in +/// @param[in] lnum line number +/// @param[out] nextp if not NULL, the line after a fold +/// @param[out] foldedp if not NULL, whether lnum is on a fold +/// @param[in] cache whether to use the window's cache for folds +/// +/// @return the total number of screen lines +int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, + bool *const foldedp, const bool cache) +{ + bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL); + if (foldedp) { + *foldedp = folded; + } + if (folded) { + return 1; + } else if (lnum == wp->w_topline) { + return plines_win_nofill(wp, lnum, true) + wp->w_topfill; + } + return plines_win(wp, lnum, true); +} + +int plines_m_win(win_T *wp, linenr_T first, linenr_T last) +{ + int count = 0; + + while (first <= last) { + linenr_T next = first; + count += plines_win_full(wp, first, &next, NULL, false); + first = next + 1; + } + return count; +} + +/// Functions calculating horizontal size of text, when displayed in a window. + +/// Return the number of characters 'c' will take on the screen, taking +/// into account the size of a tab. +/// Also see getvcol() +/// +/// @param p +/// @param col +/// +/// @return Number of characters. +int win_chartabsize(win_T *wp, char_u *p, colnr_T col) +{ + buf_T *buf = wp->w_buffer; + if (*p == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { + return tabstop_padding(col, buf->b_p_ts, buf->b_p_vts_array); + } else { + return ptr2cells(p); + } +} + +/// Return the number of characters the string 's' will take on the screen, +/// taking into account the size of a tab. +/// +/// @param s +/// +/// @return Number of characters the string will take on the screen. +int linetabsize(char_u *s) +{ + return linetabsize_col(0, s); +} + +/// Like linetabsize(), but starting at column "startcol". +/// +/// @param startcol +/// @param s +/// +/// @return Number of characters the string will take on the screen. +int linetabsize_col(int startcol, char_u *s) +{ + colnr_T col = startcol; + char_u *line = s; // pointer to start of line, for breakindent + + while (*s != NUL) { + col += lbr_chartabsize_adv(line, &s, col); + } + return (int)col; +} + +/// Like linetabsize(), but for a given window instead of the current one. +/// +/// @param wp +/// @param line +/// @param len +/// +/// @return Number of characters the string will take on the screen. +unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len) +{ + colnr_T col = 0; + + for (char_u *s = line; + *s != NUL && (len == MAXCOL || s < line + len); + MB_PTR_ADV(s)) { + col += win_lbr_chartabsize(wp, line, s, col, NULL); + } + + return (unsigned int)col; +} + +/// like win_chartabsize(), but also check for line breaks on the screen +/// +/// @param line +/// @param s +/// @param col +/// +/// @return The number of characters taken up on the screen. +int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col) +{ + if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) { + if (curwin->w_p_wrap) { + return win_nolbr_chartabsize(curwin, s, col, NULL); + } + return win_chartabsize(curwin, s, col); + } + return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL); +} + +/// Call lbr_chartabsize() and advance the pointer. +/// +/// @param line +/// @param s +/// @param col +/// +/// @return The number of characters take up on the screen. +int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col) +{ + int retval; + + retval = lbr_chartabsize(line, *s, col); + MB_PTR_ADV(*s); + return retval; +} + +/// This function is used very often, keep it fast!!!! +/// +/// If "headp" not NULL, set *headp to the size of what we for 'showbreak' +/// string at start of line. Warning: *headp is only set if it's a non-zero +/// value, init to 0 before calling. +/// +/// @param wp +/// @param line +/// @param s +/// @param col +/// @param headp +/// +/// @return The number of characters taken up on the screen. +int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, + colnr_T col, int *headp) +{ + colnr_T col2; + colnr_T col_adj = 0; // col + screen size of tab + colnr_T colmax; + int added; + int mb_added = 0; + int numberextra; + char_u *ps; + int n; + + // No 'linebreak', 'showbreak' and 'breakindent': return quickly. + if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) { + if (wp->w_p_wrap) { + return win_nolbr_chartabsize(wp, s, col, headp); + } + return win_chartabsize(wp, s, col); + } + + // First get normal size, without 'linebreak' + int size = win_chartabsize(wp, s, col); + int c = *s; + if (*s == TAB) { + col_adj = size - 1; + } + + // If 'linebreak' set check at a blank before a non-blank if the line + // needs a break here + if (wp->w_p_lbr + && vim_isbreak(c) + && !vim_isbreak((int)s[1]) + && wp->w_p_wrap + && (wp->w_width_inner != 0)) { + // Count all characters from first non-blank after a blank up to next + // non-blank after a blank. + numberextra = win_col_off(wp); + col2 = col; + colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); + + if (col >= colmax) { + colmax += col_adj; + n = colmax + win_col_off2(wp); + + if (n > 0) { + colmax += (((col - colmax) / n) + 1) * n - col_adj; + } + } + + for (;;) { + ps = s; + MB_PTR_ADV(s); + c = *s; + + if (!(c != NUL + && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) { + break; + } + + col2 += win_chartabsize(wp, s, col2); + + if (col2 >= colmax) { // doesn't fit + size = colmax - col + col_adj; + break; + } + } + } else if ((size == 2) + && (MB_BYTE2LEN(*s) > 1) + && wp->w_p_wrap + && in_win_border(wp, col)) { + // Count the ">" in the last column. + size++; + mb_added = 1; + } + + // May have to add something for 'breakindent' and/or 'showbreak' + // string at start of line. + // Set *headp to the size of what we add. + added = 0; + + if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) { + colnr_T sbrlen = 0; + int numberwidth = win_col_off(wp); + + numberextra = numberwidth; + col += numberextra + mb_added; + + if (col >= (colnr_T)wp->w_width_inner) { + col -= wp->w_width_inner; + numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp)); + if (col >= numberextra && numberextra > 0) { + col %= numberextra; + } + if (*p_sbr != NUL) { + sbrlen = (colnr_T)MB_CHARLEN(p_sbr); + if (col >= sbrlen) { + col -= sbrlen; + } + } + if (col >= numberextra && numberextra > 0) { + col %= numberextra; + } else if (col > 0 && numberextra > 0) { + col += numberwidth - win_col_off2(wp); + } + + numberwidth -= win_col_off2(wp); + } + + if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) { + if (*p_sbr != NUL) { + if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) { + // Calculate effective window width. + int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth; + int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col)) + : 0; + + if (width <= 0) { + width = 1; + } + added += ((size - prev_width) / width) * vim_strsize(p_sbr); + if ((size - prev_width) % width) { + // Wrapped, add another length of 'sbr'. + added += vim_strsize(p_sbr); + } + } else { + added += vim_strsize(p_sbr); + } + } + + if (wp->w_p_bri) { + added += get_breakindent_win(wp, line); + } + + size += added; + if (col != 0) { + added = 0; + } + } + } + + if (headp != NULL) { + *headp = added + mb_added; + } + return size; +} + +/// Like win_lbr_chartabsize(), except that we know 'linebreak' is off and +/// 'wrap' is on. This means we need to check for a double-byte character that +/// doesn't fit at the end of the screen line. +/// +/// @param wp +/// @param s +/// @param col +/// @param headp +/// +/// @return The number of characters take up on the screen. +static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp) +{ + int n; + + if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { + return tabstop_padding(col, + wp->w_buffer->b_p_ts, + wp->w_buffer->b_p_vts_array); + } + n = ptr2cells(s); + + // Add one cell for a double-width character in the last column of the + // window, displayed with a ">". + if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) { + if (headp != NULL) { + *headp = 1; + } + return 3; + } + return n; +} + diff --git a/src/nvim/plines.h b/src/nvim/plines.h new file mode 100644 index 0000000000..32778b69f1 --- /dev/null +++ b/src/nvim/plines.h @@ -0,0 +1,9 @@ +#ifndef NVIM_PLINES_H +#define NVIM_PLINES_H + +#include "nvim/vim.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "plines.h.generated.h" +#endif +#endif // NVIM_PLINES_H diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index f620517aff..1705ea0c12 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -9,6 +9,7 @@ #include <inttypes.h> #include <stdbool.h> +#include "nvim/buffer.h" #include "nvim/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" @@ -735,7 +736,7 @@ static int pum_set_selected(int n, int repeat) && (curbuf->b_p_bt[2] == 'f') && (curbuf->b_p_bh[0] == 'w')) { // Already a "wipeout" buffer, make it empty. - while (!BUFEMPTY()) { + while (!buf_is_empty(curbuf)) { ml_delete((linenr_T)1, false); } } else { diff --git a/src/nvim/profile.c b/src/nvim/profile.c index 0a5030edae..f9b0bb0a2b 100644 --- a/src/nvim/profile.c +++ b/src/nvim/profile.c @@ -250,7 +250,7 @@ void time_start(const char *message) return; } - // intialize the global variables + // initialize the global variables g_prev_time = g_start_time = profile_start(); fprintf(time_fd, "\n\ntimes in msec\n"); diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 71624baaf4..0cfb7c192f 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -54,20 +54,23 @@ struct dir_stack_T { // For each error the next struct is allocated and linked in a list. typedef struct qfline_S qfline_T; struct qfline_S { - qfline_T *qf_next; ///< pointer to next error in the list - qfline_T *qf_prev; ///< pointer to previous error in the list - linenr_T qf_lnum; ///< line number where the error occurred - int qf_fnum; ///< file number for the line - int qf_col; ///< column where the error occurred - int qf_nr; ///< error number - char_u *qf_module; ///< module name for this error - char_u *qf_pattern; ///< search pattern for the error - char_u *qf_text; ///< description of the error - char_u qf_viscol; ///< set to TRUE if qf_col is screen column - char_u qf_cleared; ///< set to TRUE if line has been deleted - char_u qf_type; ///< type of the error (mostly 'E'); 1 for - // :helpgrep - char_u qf_valid; ///< valid error message detected + qfline_T *qf_next; ///< pointer to next error in the list + qfline_T *qf_prev; ///< pointer to previous error in the list + linenr_T qf_lnum; ///< line number where the error occurred + linenr_T qf_end_lnum; ///< line number when the error has range or zero + + int qf_fnum; ///< file number for the line + int qf_col; ///< column where the error occurred + int qf_end_col; ///< column when the error has range or zero + int qf_nr; ///< error number + char_u *qf_module; ///< module name for this error + char_u *qf_pattern; ///< search pattern for the error + char_u *qf_text; ///< description of the error + char_u qf_viscol; ///< set to TRUE if qf_col and qf_end_col is + // screen column + char_u qf_cleared; ///< set to TRUE if line has been deleted + char_u qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep + char_u qf_valid; ///< valid error message detected }; // There is a stack of error lists. @@ -197,7 +200,9 @@ typedef struct { char_u *errmsg; size_t errmsglen; long lnum; + long end_lnum; int col; + int end_col; bool use_viscol; char_u *pattern; int enr; @@ -282,7 +287,9 @@ static int qf_init_process_nextline(qf_list_T *qfl, 0, fields->errmsg, fields->lnum, + fields->end_lnum, fields->col, + fields->end_col, fields->use_viscol, fields->pattern, fields->enr, @@ -1561,7 +1568,9 @@ static int qf_parse_get_fields(char_u *linebuf, size_t linelen, efm_T *fmt_ptr, fields->errmsg[0] = NUL; } fields->lnum = 0; + fields->end_lnum = 0; fields->col = 0; + fields->end_col = 0; fields->use_viscol = false; fields->enr = -1; fields->type = 0; @@ -1799,7 +1808,9 @@ void check_quickfix_busy(void) /// @param bufnum buffer number or zero /// @param mesg message /// @param lnum line number +/// @param end_lnum line number for end /// @param col column +/// @param end_col column for end /// @param vis_col using visual column /// @param pattern search pattern /// @param nr error number @@ -1808,8 +1819,9 @@ void check_quickfix_busy(void) /// /// @returns QF_OK or QF_FAIL. static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, - char_u *module, int bufnum, char_u *mesg, long lnum, - int col, char_u vis_col, char_u *pattern, int nr, + char_u *module, int bufnum, char_u *mesg, + long lnum, long end_lnum, int col, int end_col, + char_u vis_col, char_u *pattern, int nr, char_u type, char_u valid) { qfline_T *qfp = xmalloc(sizeof(qfline_T)); @@ -1828,7 +1840,9 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, } qfp->qf_text = vim_strsave(mesg); qfp->qf_lnum = lnum; + qfp->qf_end_lnum = end_lnum; qfp->qf_col = col; + qfp->qf_end_col = end_col; qfp->qf_viscol = vis_col; if (pattern == NULL || *pattern == NUL) { qfp->qf_pattern = NULL; @@ -1957,7 +1971,9 @@ static int copy_loclist_entries(const qf_list_T *from_qfl, qf_list_T *to_qfl) 0, from_qfp->qf_text, from_qfp->qf_lnum, + from_qfp->qf_end_lnum, from_qfp->qf_col, + from_qfp->qf_end_col, from_qfp->qf_viscol, from_qfp->qf_pattern, from_qfp->qf_nr, @@ -2421,7 +2437,7 @@ static qfline_T *get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx) return qf_ptr; } -/// Get a entry specied by 'errornr' and 'dir' from the current +/// Get a entry specified by 'errornr' and 'dir' from the current /// quickfix/location list. 'errornr' specifies the index of the entry and 'dir' /// specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE). /// Returns a pointer to the entry and the index of the new entry is stored in @@ -2998,6 +3014,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, } qfl->qf_index = qf_index; + qfl->qf_ptr = qf_ptr; if (qf_win_pos_update(qi, old_qf_index)) { // No need to print the error message if it's visible in the error // window @@ -3108,11 +3125,8 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) } if (qfp->qf_lnum == 0) { IObuff[0] = NUL; - } else if (qfp->qf_col == 0) { - vim_snprintf((char *)IObuff, IOSIZE, "%" PRIdLINENR, qfp->qf_lnum); } else { - vim_snprintf((char *)IObuff, IOSIZE, "%" PRIdLINENR " col %d", - qfp->qf_lnum, qfp->qf_col); + qf_range_text(qfp, IObuff, IOSIZE); } vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s", (char *)qf_types(qfp->qf_type, qfp->qf_nr)); @@ -3232,6 +3246,32 @@ static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, buf[i] = NUL; } +// Range information from lnum, col, end_lnum, and end_col. +// Put the result in "buf[bufsize]". +static void qf_range_text(const qfline_T *qfp, char_u *buf, int bufsize) +{ + vim_snprintf((char *)buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum); + int len = (int)STRLEN(buf); + + if (qfp->qf_end_lnum > 0 && qfp->qf_lnum != qfp->qf_end_lnum) { + vim_snprintf((char *)buf + len, (size_t)(bufsize - len), + "-%" PRIdLINENR, qfp->qf_end_lnum); + len += (int)STRLEN(buf + len); + } + if (qfp->qf_col > 0) { + vim_snprintf((char *)buf + len, (size_t)(bufsize - len), + " col %d", qfp->qf_col); + len += (int)STRLEN(buf + len); + if (qfp->qf_end_col > 0 && qfp->qf_col != qfp->qf_end_col) { + vim_snprintf((char *)buf + len, (size_t)(bufsize - len), + "-%d", qfp->qf_end_col); + len += (int)STRLEN(buf + len); + } + } + buf[len] = NUL; +} + + /// Display information (list number, list size and the title) about a /// quickfix/location list. static void qf_msg(qf_info_T *qi, int which, char *lead) @@ -4005,16 +4045,9 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, IObuff[len++] = '|'; } if (qfp->qf_lnum > 0) { - snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%" PRId64, - (int64_t)qfp->qf_lnum); + qf_range_text(qfp, IObuff + len, IOSIZE - len); len += (int)STRLEN(IObuff + len); - if (qfp->qf_col > 0) { - snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), " col %d", - qfp->qf_col); - len += (int)STRLEN(IObuff + len); - } - snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%s", (char *)qf_types(qfp->qf_type, qfp->qf_nr)); len += (int)STRLEN(IObuff + len); @@ -4180,7 +4213,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, // Set the 'filetype' to "qf" each time after filling the buffer. This // resembles reading a file into a buffer, it's more logical when using // autocommands. - curbuf_lock++; + curbuf->b_ro_locked++; set_option_value("ft", 0L, "qf", OPT_LOCAL); curbuf->b_p_ma = false; @@ -4190,7 +4223,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL, false, curbuf); keep_filetype = false; - curbuf_lock--; + curbuf->b_ro_locked--; // make sure it will be redrawn redraw_curbuf_later(NOT_VALID); @@ -4807,7 +4840,7 @@ static qfline_T *qf_find_entry_after_pos( FUNC_ATTR_NONNULL_ALL { if (qf_entry_after_pos(qfp, pos, linewise)) { - // First entry is after postion 'pos' + // First entry is after position 'pos' return qfp; } @@ -5263,7 +5296,9 @@ static bool vgr_match_buflines(qf_list_T *qfl, char_u *fname, buf_T *buf, ml_get_buf(buf, regmatch->startpos[0].lnum + lnum, false), regmatch->startpos[0].lnum + lnum, + regmatch->endpos[0].lnum + lnum, regmatch->startpos[0].col + 1, + regmatch->endpos[0].col + 1, false, // vis_col NULL, // search pattern 0, // nr @@ -5744,7 +5779,7 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start) } } -/// Copy the specified quickfix entry items into a new dict and appened the dict +/// Copy the specified quickfix entry items into a new dict and append the dict /// to 'list'. Returns OK on success. static int get_qfline_items(qfline_T *qfp, list_T *list) { @@ -5765,7 +5800,11 @@ static int get_qfline_items(qfline_T *qfp, list_T *list) if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum) + == FAIL) || (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col) + == FAIL) || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol) == FAIL) || (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL) @@ -6000,7 +6039,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what) if ((di = tv_dict_find(what, S_LEN("id"))) != NULL) { // Look for a list with the specified id if (di->di_tv.v_type == VAR_NUMBER) { - // For zero, use the current list or the list specifed by 'nr' + // For zero, use the current list or the list specified by 'nr' if (di->di_tv.vval.v_number != 0) { qf_idx = qf_id2nr(qi, (unsigned)di->di_tv.vval.v_number); } @@ -6263,7 +6302,9 @@ static int qf_add_entry_from_dict( char *const module = tv_dict_get_string(d, "module", true); int bufnum = (int)tv_dict_get_number(d, "bufnr"); const long lnum = (long)tv_dict_get_number(d, "lnum"); + const long end_lnum = (long)tv_dict_get_number(d, "end_lnum"); const int col = (int)tv_dict_get_number(d, "col"); + const int end_col = (int)tv_dict_get_number(d, "end_col"); const char_u vcol = (char_u)tv_dict_get_number(d, "vcol"); const int nr = (int)tv_dict_get_number(d, "nr"); const char *const type = tv_dict_get_string(d, "type", false); @@ -6301,7 +6342,9 @@ static int qf_add_entry_from_dict( bufnum, (char_u *)text, lnum, + end_lnum, col, + end_col, vcol, // vis_col (char_u *)pattern, // search pattern nr, @@ -7035,7 +7078,10 @@ static void hgr_search_file( 0, line, lnum, + 0, (int)(p_regmatch->startp[0] - line) + 1, // col + (int)(p_regmatch->endp[0] - line) + + 1, // end_col false, // vis_col NULL, // search pattern 0, // nr diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index c2ef217638..6379174938 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -63,6 +63,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/garray.h" #include "nvim/strings.h" diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 35c3285cda..039f9b4675 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1161,8 +1161,6 @@ static int nfa_regatom(void) int emit_range; int negated; int startc = -1; - int endc = -1; - int oldstartc = -1; int save_prev_at_start = prev_at_start; c = getchr(); @@ -1572,7 +1570,7 @@ collection: * Failed to recognize a character class. Use the simple * version that turns [abc] into 'a' OR 'b' OR 'c' */ - startc = endc = oldstartc = -1; + startc = -1; negated = false; if (*regparse == '^') { // negated range negated = true; @@ -1589,7 +1587,7 @@ collection: // Emit the OR branches for each character in the [] emit_range = false; while (regparse < endp) { - oldstartc = startc; + int oldstartc = startc; startc = -1; got_coll_char = false; if (*regparse == '[') { @@ -1729,7 +1727,7 @@ collection: /* Previous char was '-', so this char is end of range. */ if (emit_range) { - endc = startc; + int endc = startc; startc = oldstartc; if (startc > endc) { EMSG_RET_FAIL(_(e_reverse_range)); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 3446a944cd..38ed2816ba 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -101,6 +101,7 @@ #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/popupmnu.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" @@ -165,7 +166,7 @@ static bool resizing = false; #endif #define SEARCH_HL_PRIORITY 0 -static char * provider_first_error = NULL; +static char * provider_err = NULL; static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args, bool default_true) @@ -187,10 +188,10 @@ static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, const char *ns_name = describe_ns(ns_id); ELOG("error in provider %s:%s: %s", ns_name, name, err.msg); bool verbose_errs = true; // TODO(bfredl): - if (verbose_errs && provider_first_error == NULL) { + if (verbose_errs && provider_err == NULL) { static char errbuf[IOSIZE]; snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg); - provider_first_error = xstrdup(errbuf); + provider_err = xstrdup(errbuf); } } @@ -437,8 +438,8 @@ int update_screen(int type) } } } - redraw_cmdline = TRUE; - redraw_tabline = TRUE; + redraw_cmdline = true; + redraw_tabline = true; } msg_scrolled = 0; msg_scrolled_at_flush = 0; @@ -1186,9 +1187,12 @@ static void win_update(win_T *wp, Providers *providers) getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc); ve_flags = save_ve_flags; - ++toc; - if (curwin->w_curswant == MAXCOL) + toc++; + // Highlight to the end of the line, unless 'virtualedit' has + // "block". + if (curwin->w_curswant == MAXCOL && !(ve_flags & VE_BLOCK)) { toc = MAXCOL; + } if (fromc != wp->w_old_cursor_fcol || toc != wp->w_old_cursor_lcol) { @@ -1368,7 +1372,9 @@ static void win_update(win_T *wp, Providers *providers) // match in fixed position might need redraw // if lines were inserted or deleted || (wp->w_match_head != NULL - && buf->b_mod_xlines != 0)))))) { + && buf->b_mod_xlines != 0))))) + || (wp->w_p_cul && (lnum == wp->w_cursor.lnum + || lnum == wp->w_last_cursorline))) { if (lnum == mod_top) { top_to_mod = false; } @@ -1378,10 +1384,12 @@ static void win_update(win_T *wp, Providers *providers) * up or down to minimize redrawing. * Don't do this when the change continues until the end. * Don't scroll when dollar_vcol >= 0, keep the "$". + * Don't scroll when redrawing the top, scrolled already above. */ if (lnum == mod_top && mod_bot != MAXLNUM - && !(dollar_vcol >= 0 && mod_bot == mod_top + 1)) { + && !(dollar_vcol >= 0 && mod_bot == mod_top + 1) + && row >= top_end) { int old_rows = 0; int new_rows = 0; int xtra_rows; @@ -1687,7 +1695,7 @@ static void win_update(win_T *wp, Providers *providers) /* * There is a trick with w_botline. If we invalidate it on each * change that might modify it, this will cause a lot of expensive - * calls to plines() in update_topline() each time. Therefore the + * calls to plines_win() in update_topline() each time. Therefore the * value of w_botline is often approximated, and this value is used to * compute the value of w_topline. If the value of w_botline was * wrong, check that the value of w_topline is correct (cursor is on @@ -2003,7 +2011,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, char_u *line; // current line char_u *ptr; // current position in "line" int row; // row in the window, excl w_winrow - ScreenGrid *grid = &wp->w_grid; // grid specfic to the window + ScreenGrid *grid = &wp->w_grid; // grid specific to the window char_u extra[57]; // sign, line number and 'fdc' must // fit in here @@ -2087,7 +2095,9 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, sign_attrs_T sattrs[SIGN_SHOW_MAX]; // attributes for signs int num_signs; // number of signs for line int line_attr = 0; // attribute for the whole line + int line_attr_save; int line_attr_lowprio = 0; // low-priority attribute for the line + int line_attr_lowprio_save; matchitem_T *cur; // points to the match list match_T *shl; // points to search_hl or a match bool shl_flag; // flag to indicate whether search_hl @@ -2100,13 +2110,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool search_attr_from_match = false; // if search_attr is from :match bool has_decor = false; // this buffer has decoration - bool do_virttext = false; // draw virtual text for this line int win_col_offset = 0; // offset for window columns char_u buf_fold[FOLD_TEXT_LEN + 1]; // Hold value returned by get_foldtext bool area_active = false; + int cul_attr = 0; // set when 'cursorline' active + // 'cursorlineopt' has "screenline" and cursor is in this line + bool cul_screenline = false; + // margin columns for the screen line, needed for when 'cursorlineopt' + // contains "screenline" + int left_curline_col = 0; + int right_curline_col = 0; + /* draw_state: items that are drawn in sequence: */ #define WL_START 0 /* nothing done yet */ # define WL_CMDLINE WL_START + 1 /* cmdline window column */ @@ -2145,8 +2162,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, row = startrow; - char *err_text = NULL; - buf_T *buf = wp->w_buffer; if (!number_only) { @@ -2191,14 +2206,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } } - if (has_decor) { - extra_check = true; + if (provider_err) { + Decoration err_decor = DECORATION_INIT; + int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg")); + kv_push(err_decor.virt_text, + ((VirtTextChunk){ .text = provider_err, + .hl_id = hl_err })); + err_decor.virt_text_width = mb_string2cells((char_u *)provider_err); + decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor); + provider_err = NULL; + has_decor = true; } - if (provider_first_error) { - err_text = provider_first_error; - provider_first_error = NULL; - do_virttext = true; + if (has_decor) { + extra_check = true; } // Check for columns to display for 'colorcolumn'. @@ -2354,25 +2375,34 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, // Cursor line highlighting for 'cursorline' in the current window. if (lnum == wp->w_cursor.lnum) { - // Do not show the cursor line when Visual mode is active, because it's - // not clear what is selected then. - if (wp->w_p_cul && !(wp == curwin && VIsual_active)) { - int cul_attr = win_hl_attr(wp, HLF_CUL); + // Do not show the cursor line in the text when Visual mode is active, + // because it's not clear what is selected then. + if (wp->w_p_cul && !(wp == curwin && VIsual_active) + && wp->w_p_culopt_flags != CULOPT_NBR) { + cul_screenline = (wp->w_p_wrap + && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); + cul_attr = win_hl_attr(wp, HLF_CUL); HlAttrs ae = syn_attr2entry(cul_attr); // We make a compromise here (#7383): // * low-priority CursorLine if fg is not set // * high-priority ("same as Vim" priority) CursorLine if fg is set - if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { - line_attr_lowprio = cul_attr; - } else { - if (!(State & INSERT) && bt_quickfix(wp->w_buffer) - && qf_current_entry(wp) == lnum) { - line_attr = hl_combine_attr(cul_attr, line_attr); + if (!cul_screenline) { + if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { + line_attr_lowprio = cul_attr; } else { - line_attr = cul_attr; + if (!(State & INSERT) && bt_quickfix(wp->w_buffer) + && qf_current_entry(wp) == lnum) { + line_attr = hl_combine_attr(cul_attr, line_attr); + } else { + line_attr = cul_attr; + } } + } else { + cul_attr = 0; + margin_columns_win(wp, &left_curline_col, &right_curline_col); } + area_highlighting = true; } // Update w_last_cursorline even if Visual mode is active. wp->w_last_cursorline = wp->w_cursor.lnum; @@ -2397,6 +2427,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, area_highlighting = true; } + if (cul_screenline) { + line_attr_save = line_attr; + line_attr_lowprio_save = line_attr_lowprio; + } + line = ml_get_buf(wp->w_buffer, lnum, FALSE); ptr = line; @@ -2650,7 +2685,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, off += col; } - // wont highlight after TERM_ATTRS_MAX columns + // won't highlight after TERM_ATTRS_MAX columns int term_attrs[TERM_ATTRS_MAX] = { 0 }; if (wp->w_buffer->terminal) { terminal_get_line_attributes(wp->w_buffer->terminal, wp, lnum, term_attrs); @@ -2779,11 +2814,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, if (num_sattr != NULL) { // :sign defined with "numhl" highlight. char_attr = num_sattr->sat_numhl; - } else if ((wp->w_p_cul || wp->w_p_rnu) + } else if (wp->w_p_cul && lnum == wp->w_cursor.lnum + && (wp->w_p_culopt_flags & CULOPT_NBR) + && (row == startrow + || wp->w_p_culopt_flags & CULOPT_LINE) && filler_todo == 0) { // When 'cursorline' is set highlight the line number of // the current line differently. + // When 'cursorlineopt' has "screenline" only highlight + // the line number itself. // TODO(vim): Can we use CursorLine instead of CursorLineNr // when CursorLineNr isn't set? char_attr = win_hl_attr(wp, HLF_CLN); @@ -2815,8 +2855,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, if (diff_hlf != (hlf_T)0) { char_attr = win_hl_attr(wp, diff_hlf); - if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { - char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL)); + if (cul_attr) { + char_attr = hl_combine_attr(char_attr, cul_attr); } } p_extra = NULL; @@ -2875,8 +2915,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, if (tocol == vcol) tocol += n_extra; // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'. - if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { - char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), char_attr); + if (cul_attr) { + char_attr = hl_combine_attr(cul_attr, char_attr); } } } @@ -2903,6 +2943,24 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } } + if (cul_screenline) { + if (draw_state == WL_LINE + && vcol >= left_curline_col + && vcol < right_curline_col) { + cul_attr = win_hl_attr(wp, HLF_CUL); + HlAttrs ae = syn_attr2entry(cul_attr); + if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { + line_attr_lowprio = cul_attr; + } else { + line_attr = cul_attr; + } + } else { + cul_attr = 0; + line_attr = line_attr_save; + line_attr_lowprio = line_attr_lowprio_save; + } + } + // When still displaying '$' of change command, stop at cursor if (((dollar_vcol >= 0 && wp == curwin @@ -3110,12 +3168,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } line_attr = win_hl_attr(wp, diff_hlf); // Overlay CursorLine onto diff-mode highlight. - if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { + if (cul_attr) { line_attr = 0 != line_attr_lowprio // Low-priority CursorLine - ? hl_combine_attr(hl_combine_attr(win_hl_attr(wp, HLF_CUL), - line_attr), + ? hl_combine_attr(hl_combine_attr(cul_attr, line_attr), hl_get_underline()) - : hl_combine_attr(line_attr, win_hl_attr(wp, HLF_CUL)); + : hl_combine_attr(line_attr, cul_attr); } } @@ -3191,6 +3248,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, (void)mb_l; multi_attr = win_hl_attr(wp, HLF_AT); + if (cul_attr) { + multi_attr = 0 != line_attr_lowprio + ? hl_combine_attr(cul_attr, multi_attr) + : hl_combine_attr(multi_attr, cul_attr); + } + // put the pointer back to output the double-width // character at the start of the next line. n_extra++; @@ -3351,7 +3414,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, ptr = line + v; if (!attr_pri) { - char_attr = syntax_attr; + if (cul_attr) { + char_attr = 0 != line_attr_lowprio + ? hl_combine_attr(cul_attr, syntax_attr) + : hl_combine_attr(syntax_attr, cul_attr); + } else { + char_attr = syntax_attr; + } } else { char_attr = hl_combine_attr(syntax_attr, char_attr); } @@ -3918,8 +3987,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } int eol_attr = char_attr; - if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { - eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr); + if (cul_attr) { + eol_attr = hl_combine_attr(cul_attr, eol_attr); } linebuf_attr[off] = eol_attr; if (wp->w_p_rl) { @@ -3950,19 +4019,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, if (draw_color_col) draw_color_col = advance_color_col(VCOL_HLC, &color_cols); - VirtText virt_text = KV_INITIAL_VALUE; - bool has_aligned = false; - if (err_text) { - int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg")); - kv_push(virt_text, ((VirtTextChunk){ .text = err_text, - .hl_id = hl_err })); - do_virttext = true; - } else if (has_decor) { - virt_text = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr, - &has_aligned); - if (kv_size(virt_text)) { - do_virttext = true; - } + bool has_virttext = false; + // Make sure alignment is the same regardless + // if listchars=eol:X is used or not. + int eol_skip = (wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0 + ? 1 : 0); + + if (has_decor) { + has_virttext = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr, + col + eol_skip); } if (((wp->w_p_cuc @@ -3971,20 +4036,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, grid->Columns * (row - startrow + 1) + v && lnum != wp->w_cursor.lnum) || draw_color_col || line_attr_lowprio || line_attr - || diff_hlf != (hlf_T)0 || do_virttext - || has_aligned)) { + || diff_hlf != (hlf_T)0 || has_virttext)) { int rightmost_vcol = 0; int i; - size_t virt_pos = 0; - LineState s = LINE_STATE(""); - int virt_attr = 0; - - // Make sure alignment is the same regardless - // if listchars=eol:X is used or not. - bool delay_virttext = wp->w_p_lcs_chars.eol == lcs_eol_one - && eol_hl_off == 0; - if (wp->w_p_cuc) { rightmost_vcol = wp->w_virtcol; } @@ -4010,37 +4065,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } int base_attr = hl_combine_attr(line_attr_lowprio, diff_attr); - if (base_attr || line_attr || has_aligned) { + if (base_attr || line_attr || has_virttext) { rightmost_vcol = INT_MAX; } int col_stride = wp->w_p_rl ? -1 : 1; while (wp->w_p_rl ? col >= 0 : col < grid->Columns) { - int cells = -1; - if (do_virttext && !delay_virttext) { - if (*s.p == NUL) { - if (virt_pos < virt_text.size) { - s.p = kv_A(virt_text, virt_pos).text; - int hl_id = kv_A(virt_text, virt_pos).hl_id; - virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; - virt_pos++; - } else { - do_virttext = false; - } - } - if (*s.p != NUL) { - cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col, - false); - } - } - delay_virttext = false; - - if (cells == -1) { - schar_from_ascii(linebuf_char[off], ' '); - cells = 1; - } - col += cells * col_stride; + schar_from_ascii(linebuf_char[off], ' '); + col += col_stride; if (draw_color_col) { draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } @@ -4053,24 +4086,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, col_attr = mc_attr; } - if (do_virttext) { - col_attr = hl_combine_attr(col_attr, virt_attr); - } - col_attr = hl_combine_attr(col_attr, line_attr); linebuf_attr[off] = col_attr; - if (cells == 2) { - linebuf_attr[off+1] = col_attr; - } - off += cells * col_stride; + off += col_stride; - if (VCOL_HLC >= rightmost_vcol && *s.p == NUL - && virt_pos >= virt_text.size) { + if (VCOL_HLC >= rightmost_vcol) { break; } - vcol += cells; + vcol += 1; } } @@ -4095,7 +4120,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, /* * Update w_cline_height and w_cline_folded if the cursor line was - * updated (saves a call to plines() later). + * updated (saves a call to plines_win() later). */ if (wp == curwin && lnum == curwin->w_cursor.lnum) { curwin->w_cline_row = startrow; @@ -4389,7 +4414,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } xfree(p_extra_free); - xfree(err_text); return row; } @@ -4397,13 +4421,17 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col) { DecorState *state = &decor_state; int right_pos = max_col; + bool do_eol = state->eol_col > -1; for (size_t i = 0; i < kv_size(state->active); i++) { DecorRange *item = &kv_A(state->active, i); if (item->start_row == state->row && kv_size(item->decor.virt_text)) { if (item->win_col == -1) { if (item->decor.virt_text_pos == kVTRightAlign) { - right_pos -= item->decor.col; + right_pos -= item->decor.virt_text_width; item->win_col = right_pos; + } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) { + item->win_col = state->eol_col; + state->eol_col += item->decor.virt_text_width; } else if (item->decor.virt_text_pos == kVTWinCol) { item->win_col = MAX(item->decor.col+col_off, 0); } @@ -4421,14 +4449,20 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col) while (col < max_col) { if (!*s.p) { - if (virt_pos == kv_size(vt)) { + if (virt_pos >= kv_size(vt)) { + break; + } + virt_attr = 0; + do { + s.p = kv_A(vt, virt_pos).text; + int hl_id = kv_A(vt, virt_pos).hl_id; + virt_attr = hl_combine_attr(virt_attr, + hl_id > 0 ? syn_id2attr(hl_id) : 0); + virt_pos++; + } while (!s.p && virt_pos < kv_size(vt)); + if (!s.p) { break; } - s.p = kv_A(vt, virt_pos).text; - int hl_id = kv_A(vt, virt_pos).hl_id; - virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; - virt_pos++; - continue; } int attr; bool through = false; @@ -5527,7 +5561,7 @@ static void win_redr_border(win_T *wp) } } -// Low-level functions to manipulate invidual character cells on the +// Low-level functions to manipulate individual character cells on the // screen grid. /// Put a ASCII character in a screen cell. @@ -6783,8 +6817,8 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // Show the current mode and ruler. // -// If clear_cmdline is TRUE, clear the rest of the cmdline. -// If clear_cmdline is FALSE there may be a message there that needs to be +// If clear_cmdline is true, clear the rest of the cmdline. +// If clear_cmdline is false there may be a message there that needs to be // cleared only if a mode is shown. // Return the length of the message (0 if no message). int showmode(void) @@ -6793,7 +6827,6 @@ int showmode(void) int length = 0; int do_mode; int attr; - int nwr_save; int sub_attr; if (ui_has(kUIMessages) && clear_cmdline) { @@ -6815,11 +6848,11 @@ int showmode(void) // Call char_avail() only when we are going to show something, because // it takes a bit of time. if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) { - redraw_cmdline = TRUE; /* show mode later */ + redraw_cmdline = true; // show mode later return 0; } - nwr_save = need_wait_return; + bool nwr_save = need_wait_return; /* wait a bit before overwriting an important message */ check_for_delay(FALSE); @@ -6834,7 +6867,7 @@ int showmode(void) msg_pos_mode(); attr = HL_ATTR(HLF_CM); // Highlight mode - // When the screen is too narrow to show the entire mode messsage, + // When the screen is too narrow to show the entire mode message, // avoid scrolling and truncate instead. msg_no_more = true; int save_lines_left = lines_left; @@ -6936,10 +6969,11 @@ int showmode(void) need_clear = true; } - mode_displayed = TRUE; - if (need_clear || clear_cmdline) + mode_displayed = true; + if (need_clear || clear_cmdline) { msg_clr_eos(); - msg_didout = FALSE; /* overwrite this message */ + } + msg_didout = false; // overwrite this message length = msg_col; msg_col = 0; msg_no_more = false; @@ -6950,7 +6984,7 @@ int showmode(void) msg_clr_cmdline(); } - // NB: also handles clearing the showmode if it was emtpy or disabled + // NB: also handles clearing the showmode if it was empty or disabled msg_ext_flush_showmode(); /* In Visual mode the size of the selected area must be redrawn. */ @@ -7195,7 +7229,7 @@ void draw_tabline(void) /* Reset the flag here again, in case evaluating 'tabline' causes it to be * set. */ - redraw_tabline = FALSE; + redraw_tabline = false; } void ui_ext_tabline_update(void) @@ -7539,6 +7573,49 @@ int number_width(win_T *wp) return n; } +/// Used when 'cursorlineopt' contains "screenline": compute the margins between +/// which the highlighting is used. +static void margin_columns_win(win_T *wp, int *left_col, int *right_col) +{ + // cache previous calculations depending on w_virtcol + static int saved_w_virtcol; + static win_T *prev_wp; + static int prev_left_col; + static int prev_right_col; + static int prev_col_off; + + int cur_col_off = win_col_off(wp); + int width1; + int width2; + + if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp + && prev_col_off == cur_col_off) { + *right_col = prev_right_col; + *left_col = prev_left_col; + return; + } + + width1 = wp->w_width - cur_col_off; + width2 = width1 + win_col_off2(wp); + + *left_col = 0; + *right_col = width1; + + if (wp->w_virtcol >= (colnr_T)width1) { + *right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2; + } + if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) { + *left_col = (wp->w_virtcol - width1) / width2 * width2 + width1; + } + + // cache values + prev_left_col = *left_col; + prev_right_col = *right_col; + prev_wp = wp; + saved_w_virtcol = wp->w_virtcol; + prev_col_off = cur_col_off; +} + /// Set dimensions of the Nvim application "shell". void screen_resize(int width, int height) { diff --git a/src/nvim/search.c b/src/nvim/search.c index 82fc0f9d8e..e5d545b185 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -137,7 +137,7 @@ search_regcomp( int magic; int i; - rc_did_emsg = FALSE; + rc_did_emsg = false; magic = p_magic; /* @@ -153,7 +153,7 @@ search_regcomp( EMSG(_(e_nopresub)); else EMSG(_(e_noprevre)); - rc_did_emsg = TRUE; + rc_did_emsg = true; return FAIL; } pat = spats[i].pat; @@ -474,7 +474,7 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) spats[idx].timestamp = os_time(); spats[idx].additional_data = NULL; spats[idx].magic = magic; - spats[idx].no_scs = FALSE; + spats[idx].no_scs = false; spats[idx].off.dir = '/'; set_vv_searchforward(); spats[idx].off.line = FALSE; @@ -1501,7 +1501,7 @@ int searchc(cmdarg_T *cap, int t_cmd) FUNC_ATTR_NONNULL_ALL { int c = cap->nchar; // char to search for - Direction dir = cap->arg; // TRUE for searching forward + int dir = cap->arg; // true for searching forward long count = cap->count1; // repeat count int col; char_u *p; @@ -3110,7 +3110,7 @@ current_word( inc_cursor(); if (VIsual_mode == 'V') { VIsual_mode = 'v'; - redraw_cmdline = TRUE; /* show mode later */ + redraw_cmdline = true; // show mode later } } else oap->inclusive = inclusive; @@ -4105,7 +4105,7 @@ bool current_quote( } if (VIsual_mode == 'V') { VIsual_mode = 'v'; - redraw_cmdline = TRUE; /* show mode later */ + redraw_cmdline = true; // show mode later } } else { /* Set inclusive and other oap's flags. */ @@ -4451,7 +4451,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, // Unfortunately, there is no STRNICMP function. // XXX: above comment should be "no MB_STRCMP function" ? if (!(chgtick == buf_get_changedtick(curbuf) - && lastpat != NULL // supress clang/NULL passed as nonnull parameter + && lastpat != NULL // suppress clang/NULL passed as nonnull parameter && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0 && STRLEN(lastpat) == STRLEN(spats[last_idx].pat) && equalpos(lastpos, *cursor_pos) diff --git a/src/nvim/search.h b/src/nvim/search.h index 98ddaa5eeb..0dbaf79c37 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -88,7 +88,7 @@ typedef struct searchstat { int cur; // current position of found words int cnt; // total count of found words - int exact_match; // TRUE if matched exactly on specified position + bool exact_match; // true if matched exactly on specified position int incomplete; // 0: search was fully completed // 1: recomputing was timed out // 2: max count exceeded diff --git a/src/nvim/sign.c b/src/nvim/sign.c index 15fd25e096..c6f59b42b8 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -115,10 +115,10 @@ static void sign_group_unref(char_u *groupname) } } -/// Returns TRUE if 'sign' is in 'group'. +/// @return true if 'sign' is in 'group'. /// A sign can either be in the global group (sign->group == NULL) /// or in a named group. If 'group' is '*', then the sign is part of the group. -int sign_in_group(sign_entry_T *sign, const char_u *group) +bool sign_in_group(sign_entry_T *sign, const char_u *group) { return ((group != NULL && STRCMP(group, "*") == 0) || (group == NULL && sign->se_group == NULL) @@ -143,7 +143,7 @@ int sign_group_get_next_signid(buf_T *buf, const char_u *groupname) group = HI2SG(hi); } - // Search for the next usuable sign identifier + // Search for the next usable sign identifier while (!found) { if (group == NULL) { id = next_sign_id++; // global group @@ -194,7 +194,7 @@ static void insert_sign( if (next != NULL) { next->se_prev = newsign; } - buf->b_signcols_max = -1; + buf->b_signcols_valid = false; if (prev == NULL) { // When adding first sign need to redraw the windows to create the @@ -534,7 +534,7 @@ linenr_T buf_delsign( sign_entry_T *next; // the next sign in a b_signlist linenr_T lnum; // line number whose sign was deleted - buf->b_signcols_max = -1; + buf->b_signcols_valid = false; lastp = &buf->b_signlist; lnum = 0; for (sign = buf->b_signlist; sign != NULL; sign = next) { @@ -668,7 +668,7 @@ void buf_delete_signs(buf_T *buf, char_u *group) lastp = &sign->se_next; } } - buf->b_signcols_max = -1; + buf->b_signcols_valid = false; } /// List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers. @@ -735,7 +735,7 @@ void sign_mark_adjust( int is_fixed = 0; int signcol = win_signcol_configured(curwin, &is_fixed); - curbuf->b_signcols_max = -1; + curbuf->b_signcols_valid = false; lastp = &curbuf->b_signlist; for (sign = curbuf->b_signlist; sign != NULL; sign = next) { diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 771c2106db..28276884b0 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -6672,7 +6672,7 @@ void ex_spelldump(exarg_T *eap) set_option_value("spl", dummy, (char *)spl, OPT_LOCAL); xfree(spl); - if (!BUFEMPTY()) { + if (!buf_is_empty(curbuf)) { return; } diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 0597f392e7..15271e831c 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -3945,7 +3945,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int msg_start(); msg_puts(_(msg_compressing)); msg_clr_eos(); - msg_didout = FALSE; + msg_didout = false; msg_col = 0; ui_flush(); } diff --git a/src/nvim/state.c b/src/nvim/state.c index a3c74789d1..02d63d8ab1 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -144,6 +144,9 @@ char *get_mode(void) buf[0] = (char)(VIsual_mode + 's' - 'v'); } else { buf[0] = (char)VIsual_mode; + if (restart_VIsual_select) { + buf[1] = 's'; + } } } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE || State == CONFIRM) { @@ -171,12 +174,10 @@ char *get_mode(void) buf[1] = 'x'; } } - } else if ((State & CMDLINE) || exmode_active) { + } else if (State & CMDLINE) { buf[0] = 'c'; - if (exmode_active == EXMODE_VIM) { + if (exmode_active) { buf[1] = 'v'; - } else if (exmode_active == EXMODE_NORMAL) { - buf[1] = 'e'; } } else if (State & TERM_FOCUS) { buf[0] = 't'; diff --git a/src/nvim/strings.c b/src/nvim/strings.c index cb66f7682d..0363afe02d 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -964,7 +964,7 @@ int vim_vsnprintf_typval( break; } } - str_arg_l = precision = (size_t)(p1 - (char_u *)str_arg); + str_arg_l = (size_t)(p1 - (char_u *)str_arg); } } break; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index ce81f26d38..e9ee63970c 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3417,16 +3417,6 @@ static void syn_cmd_on(exarg_T *eap, int syncing) } /* - * Handle ":syntax enable" command. - */ -static void syn_cmd_enable(exarg_T *eap, int syncing) -{ - set_internal_string_var("syntax_cmd", (char_u *)"enable"); - syn_cmd_onoff(eap, "syntax"); - do_unlet(S_LEN("g:syntax_cmd"), true); -} - -/* * Handle ":syntax reset" command. * It actually resets highlighting, not syntax. */ @@ -3434,9 +3424,7 @@ static void syn_cmd_reset(exarg_T *eap, int syncing) { eap->nextcmd = check_nextcmd(eap->arg); if (!eap->skip) { - set_internal_string_var("syntax_cmd", (char_u *)"reset"); - do_cmdline_cmd("runtime! syntax/syncolor.vim"); - do_unlet(S_LEN("g:syntax_cmd"), true); + init_highlight(true, true); } } @@ -3475,7 +3463,7 @@ void syn_maybe_enable(void) exarg_T ea; ea.arg = (char_u *)""; ea.skip = false; - syn_cmd_enable(&ea, false); + syn_cmd_on(&ea, false); } } @@ -5534,7 +5522,7 @@ static struct subcommand subcommands[] = { "clear", syn_cmd_clear }, { "cluster", syn_cmd_cluster }, { "conceal", syn_cmd_conceal }, - { "enable", syn_cmd_enable }, + { "enable", syn_cmd_on }, { "foldlevel", syn_cmd_foldlevel }, { "include", syn_cmd_include }, { "iskeyword", syn_cmd_iskeyword }, @@ -6057,6 +6045,34 @@ static const char *highlight_init_both[] = { "RedrawDebugClear ctermbg=Yellow guibg=Yellow", "RedrawDebugComposed ctermbg=Green guibg=Green", "RedrawDebugRecompose ctermbg=Red guibg=Red", + "Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE " + "guifg=White guibg=Red", + "Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE " + "guifg=Blue guibg=Yellow", + "default link String Constant", + "default link Character Constant", + "default link Number Constant", + "default link Boolean Constant", + "default link Float Number", + "default link Function Identifier", + "default link Conditional Statement", + "default link Repeat Statement", + "default link Label Statement", + "default link Operator Statement", + "default link Keyword Statement", + "default link Exception Statement", + "default link Include PreProc", + "default link Define PreProc", + "default link Macro PreProc", + "default link PreCondit PreProc", + "default link StorageClass Type", + "default link Structure Type", + "default link Typedef Type", + "default link Tag Special", + "default link SpecialChar Special", + "default link Delimiter Special", + "default link SpecialComment Special", + "default link Debug Special", NULL }; @@ -6065,7 +6081,7 @@ static const char *highlight_init_light[] = { "ColorColumn ctermbg=LightRed guibg=LightRed", "CursorColumn ctermbg=LightGrey guibg=Grey90", "CursorLine cterm=underline guibg=Grey90", - "CursorLineNr ctermfg=Brown gui=bold guifg=Brown", + "CursorLineNr cterm=underline ctermfg=Brown gui=bold guifg=Brown", "DiffAdd ctermbg=LightBlue guibg=LightBlue", "DiffChange ctermbg=LightMagenta guibg=LightMagenta", "DiffDelete ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan", @@ -6090,6 +6106,24 @@ static const char *highlight_init_light[] = { "Title ctermfg=DarkMagenta gui=bold guifg=Magenta", "Visual guibg=LightGrey", "WarningMsg ctermfg=DarkRed guifg=Red", + "Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE " + "gui=NONE guifg=Blue guibg=NONE", + "Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE " + "gui=NONE guifg=Magenta guibg=NONE", + "Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE " + "gui=NONE guifg=#6a5acd guibg=NONE", + "Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE " + "gui=NONE guifg=DarkCyan guibg=NONE", + "Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE " + "gui=bold guifg=Brown guibg=NONE", + "PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE " + "gui=NONE guifg=#6a0dad guibg=NONE", + "Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE " + "gui=bold guifg=SeaGreen guibg=NONE", + "Underlined term=underline cterm=underline ctermfg=DarkMagenta " + "gui=underline guifg=SlateBlue", + "Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE " + "gui=NONE guifg=bg guibg=NONE", NULL }; @@ -6098,7 +6132,7 @@ static const char *highlight_init_dark[] = { "ColorColumn ctermbg=DarkRed guibg=DarkRed", "CursorColumn ctermbg=DarkGrey guibg=Grey40", "CursorLine cterm=underline guibg=Grey40", - "CursorLineNr ctermfg=Yellow gui=bold guifg=Yellow", + "CursorLineNr cterm=underline ctermfg=Yellow gui=bold guifg=Yellow", "DiffAdd ctermbg=DarkBlue guibg=DarkBlue", "DiffChange ctermbg=DarkMagenta guibg=DarkMagenta", "DiffDelete ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan", @@ -6123,11 +6157,29 @@ static const char *highlight_init_dark[] = { "Title ctermfg=LightMagenta gui=bold guifg=Magenta", "Visual guibg=DarkGrey", "WarningMsg ctermfg=LightRed guifg=Red", + "Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE " + "gui=NONE guifg=#80a0ff guibg=NONE", + "Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE " + "gui=NONE guifg=#ffa0a0 guibg=NONE", + "Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE " + "gui=NONE guifg=Orange guibg=NONE", + "Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE " + "gui=NONE guifg=#40ffff guibg=NONE", + "Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE " + "gui=bold guifg=#ffff60 guibg=NONE", + "PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE " + "gui=NONE guifg=#ff80ff guibg=NONE", + "Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE " + "gui=bold guifg=#60ff60 guibg=NONE", + "Underlined term=underline cterm=underline ctermfg=LightBlue " + "gui=underline guifg=#80a0ff", + "Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE " + "gui=NONE guifg=bg guibg=NONE", NULL }; const char *const highlight_init_cmdline[] = { - // XXX When modifying a list modify it in both valid and invalid halfs. + // XXX When modifying a list modify it in both valid and invalid halves. // TODO(ZyX-I): merge valid and invalid groups via a macros. // NvimInternalError should appear only when highlighter has a bug. @@ -6398,20 +6450,6 @@ void init_highlight(bool both, bool reset) } } - /* - * If syntax highlighting is enabled load the highlighting for it. - */ - if (get_var_value("g:syntax_on") != NULL) { - static int recursive = 0; - - if (recursive >= 5) { - EMSG(_("E679: recursive loop loading syncolor.vim")); - } else { - recursive++; - (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL); - recursive--; - } - } syn_init_cmdline_highlight(false, false); } @@ -7703,7 +7741,7 @@ void highlight_changed(void) int id_SNC = 0; int hlcnt; - need_highlight_changed = FALSE; + need_highlight_changed = false; /// Translate builtin highlight groups into attributes for quick lookup. for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { diff --git a/src/nvim/tag.c b/src/nvim/tag.c index ab35c936ca..d6c6b064b2 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2611,7 +2611,6 @@ static int jumpto_tag( int keep_help // keep help flag (FALSE for cscope) ) { - int save_secure; int save_magic; bool save_p_ws; int save_p_scs, save_p_ic; @@ -2766,9 +2765,6 @@ static int jumpto_tag( curwin->w_set_curswant = true; postponed_split = 0; - save_secure = secure; - secure = 1; - ++sandbox; save_magic = p_magic; p_magic = false; // always execute with 'nomagic' // Save value of no_hlsearch, jumping to a tag is not a real search @@ -2866,21 +2862,26 @@ static int jumpto_tag( * of the line. May need to correct that here. */ check_cursor(); } else { - curwin->w_cursor.lnum = 1; /* start command in line 1 */ + const int save_secure = secure; + + // Setup the sandbox for executing the command from the tags file. + secure = 1; + sandbox++; + curwin->w_cursor.lnum = 1; // start command in line 1 do_cmdline_cmd((char *)pbuf); retval = OK; + + // When the command has done something that is not allowed make sure + // the error message can be seen. + if (secure == 2) { + wait_return(true); + } + secure = save_secure; + sandbox--; } - /* - * When the command has done something that is not allowed make sure - * the error message can be seen. - */ - if (secure == 2) - wait_return(TRUE); - secure = save_secure; p_magic = save_magic; - --sandbox; - /* restore no_hlsearch when keeping the old search pattern */ + // restore no_hlsearch when keeping the old search pattern if (search_options) { set_no_hlsearch(save_no_hlsearch); } @@ -3291,7 +3292,7 @@ static void tagstack_clear(win_T *wp) } // Remove the oldest entry from the tag stack and shift the rest of -// the entires to free up the top of the stack. +// the entries to free up the top of the stack. static void tagstack_shift(win_T *wp) { taggy_T *tagstack = wp->w_tagstack; diff --git a/src/nvim/testdir/check.vim b/src/nvim/testdir/check.vim index 7b06e53dd5..14bab33a2f 100644 --- a/src/nvim/testdir/check.vim +++ b/src/nvim/testdir/check.vim @@ -9,6 +9,17 @@ func CheckFeature(name) endif endfunc +" Command to check for the absence of a feature. +command -nargs=1 CheckNotFeature call CheckNotFeature(<f-args>) +func CheckNotFeature(name) + if !has(a:name, 1) + throw 'Checking for non-existent feature ' .. a:name + endif + if has(a:name) + throw 'Skipped: ' .. a:name .. ' feature present' + endif +endfunc + " Command to check for the presence of a working option. command -nargs=1 CheckOption call CheckOption(<f-args>) func CheckOption(name) diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c index c71a5c8f40..7023064637 100644 --- a/src/nvim/testdir/samples/memfile_test.c +++ b/src/nvim/testdir/samples/memfile_test.c @@ -37,8 +37,8 @@ test_mf_hash(void) mf_hashtab_T ht; mf_hashitem_T *item; blocknr_T key; - long_u i; - long_u num_buckets; + size_t i; + size_t num_buckets; mf_hash_init(&ht); diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index fd9cfb54be..fcbc28fdc0 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -20,7 +20,7 @@ set tags=./tags,tags set undodir^=. set wildoptions= set startofline -set sessionoptions&vi +set sessionoptions+=options " Prevent Nvim log from writing to stderr. let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log' diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index b5c50b5894..cc767a9bcf 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -7,6 +7,7 @@ source test_cd.vim source test_changedtick.vim source test_compiler.vim source test_cursor_func.vim +source test_cursorline.vim source test_ex_equal.vim source test_ex_undo.vim source test_ex_z.vim diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim index ff5029b889..5542746a04 100644 --- a/src/nvim/testdir/test_breakindent.vim +++ b/src/nvim/testdir/test_breakindent.vim @@ -16,6 +16,10 @@ func s:screen_lines(lnum, width) abort return ScreenLines([a:lnum, a:lnum + 2], a:width) endfunc +func s:screen_lines2(lnums, lnume, width) abort + return ScreenLines([a:lnums, a:lnume], a:width) +endfunc + func! s:compare_lines(expect, actual) call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) endfunc @@ -745,4 +749,123 @@ func Test_breakindent20_cpo_n_nextpage() call s:close_windows('set breakindent& briopt& cpo& number&') endfunc +func Test_breakindent20_list() + call s:test_windows('setl breakindent breakindentopt= linebreak') + " default: + call setline(1, [' 1. Congress shall make no law', + \ ' 2.) Congress shall make no law', + \ ' 3.] Congress shall make no law']) + norm! 1gg + redraw! + let lines = s:screen_lines2(1, 6, 20) + let expect = [ + \ " 1. Congress ", + \ "shall make no law ", + \ " 2.) Congress ", + \ "shall make no law ", + \ " 3.] Congress ", + \ "shall make no law ", + \ ] + call s:compare_lines(expect, lines) + " set mininum indent + setl briopt=min:5 + redraw! + let lines = s:screen_lines2(1, 6, 20) + let expect = [ + \ " 1. Congress ", + \ " shall make no law ", + \ " 2.) Congress ", + \ " shall make no law ", + \ " 3.] Congress ", + \ " shall make no law ", + \ ] + call s:compare_lines(expect, lines) + " set additional handing indent + setl briopt+=list:4 + redraw! + let expect = [ + \ " 1. Congress ", + \ " shall make no ", + \ " law ", + \ " 2.) Congress ", + \ " shall make no ", + \ " law ", + \ " 3.] Congress ", + \ " shall make no ", + \ " law ", + \ ] + let lines = s:screen_lines2(1, 9, 20) + call s:compare_lines(expect, lines) + + " reset linebreak option + " Note: it indents by one additional + " space, because of the leading space. + setl linebreak&vim list listchars=eol:$,space:_ + redraw! + let expect = [ + \ "__1.__Congress_shall", + \ " _make_no_law$ ", + \ "__2.)_Congress_shall", + \ " _make_no_law$ ", + \ "__3.]_Congress_shall", + \ " _make_no_law$ ", + \ ] + let lines = s:screen_lines2(1, 6, 20) + call s:compare_lines(expect, lines) + + " check formatlistpat indent + setl briopt=min:5,list:-1 + setl linebreak list&vim listchars&vim + let &l:flp = '^\s*\d\+\.\?[\]:)}\t ]\s*' + redraw! + let expect = [ + \ " 1. Congress ", + \ " shall make no ", + \ " law ", + \ " 2.) Congress ", + \ " shall make no ", + \ " law ", + \ " 3.] Congress ", + \ " shall make no ", + \ " law ", + \ ] + let lines = s:screen_lines2(1, 9, 20) + call s:compare_lines(expect, lines) + " check formatlistpat indent with different list levels + let &l:flp = '^\s*\*\+\s\+' + redraw! + %delete _ + call setline(1, ['* Congress shall make no law', + \ '*** Congress shall make no law', + \ '**** Congress shall make no law']) + norm! 1gg + let expect = [ + \ "* Congress shall ", + \ " make no law ", + \ "*** Congress shall ", + \ " make no law ", + \ "**** Congress shall ", + \ " make no law ", + \ ] + let lines = s:screen_lines2(1, 6, 20) + call s:compare_lines(expect, lines) + + " check formatlistpat indent with different list level + " showbreak and sbr + setl briopt=min:5,sbr,list:-1,shift:2 + setl showbreak=> + redraw! + let expect = [ + \ "* Congress shall ", + \ "> make no law ", + \ "*** Congress shall ", + \ "> make no law ", + \ "**** Congress shall ", + \ "> make no law ", + \ ] + let lines = s:screen_lines2(1, 6, 20) + call s:compare_lines(expect, lines) + call s:close_windows('set breakindent& briopt& linebreak& list& listchars& showbreak&') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim index 770ed55b8d..02a23bf82f 100644 --- a/src/nvim/testdir/test_cd.vim +++ b/src/nvim/testdir/test_cd.vim @@ -1,4 +1,7 @@ -" Test for :cd +" Test for :cd and chdir() + +source shared.vim +source check.vim func Test_cd_large_path() " This used to crash with a heap write overflow. @@ -65,3 +68,18 @@ func Test_cd_with_cpo_chdir() set cpo& bw! endfunc + +func Test_cd_from_non_existing_dir() + CheckNotMSWindows + + let saveddir = getcwd() + call mkdir('Xdeleted_dir') + cd Xdeleted_dir + call delete(saveddir .. '/Xdeleted_dir', 'd') + + " Expect E187 as the current directory was deleted. + call assert_fails('pwd', 'E187:') + call assert_equal('', getcwd()) + cd - + call assert_equal(saveddir, getcwd()) +endfunc diff --git a/src/nvim/testdir/test_cursorline.vim b/src/nvim/testdir/test_cursorline.vim new file mode 100644 index 0000000000..4a0f2665fe --- /dev/null +++ b/src/nvim/testdir/test_cursorline.vim @@ -0,0 +1,249 @@ +" Test for cursorline and cursorlineopt + +source check.vim +source screendump.vim + +function! s:screen_attr(lnum) abort + return map(range(1, 8), 'screenattr(a:lnum, v:val)') +endfunction + +function! s:test_windows(h, w) abort + call NewWindow(a:h, a:w) +endfunction + +function! s:close_windows() abort + call CloseWindow() +endfunction + +function! s:new_hi() abort + redir => save_hi + silent! hi CursorLineNr + redir END + let save_hi = join(split(substitute(save_hi, '\s*xxx\s*', ' ', ''), "\n"), '') + exe 'hi' save_hi 'ctermbg=0 guibg=Black' + return save_hi +endfunction + +func Test_cursorline_highlight1() + let save_hi = s:new_hi() + try + call s:test_windows(10, 20) + call setline(1, repeat(['aaaa'], 10)) + redraw + let attr01 = s:screen_attr(1) + call assert_equal(repeat([attr01[0]], 8), attr01) + + setl number numberwidth=4 + redraw + let attr11 = s:screen_attr(1) + call assert_equal(repeat([attr11[0]], 4), attr11[0:3]) + call assert_equal(repeat([attr11[4]], 4), attr11[4:7]) + call assert_notequal(attr11[0], attr11[4]) + + setl cursorline + redraw + let attr21 = s:screen_attr(1) + let attr22 = s:screen_attr(2) + call assert_equal(repeat([attr21[0]], 4), attr21[0:3]) + call assert_equal(repeat([attr21[4]], 4), attr21[4:7]) + call assert_equal(attr11, attr22) + call assert_notequal(attr22, attr21) + + setl nocursorline relativenumber + redraw + let attr31 = s:screen_attr(1) + call assert_equal(attr22[0:3], attr31[0:3]) + call assert_equal(attr11[4:7], attr31[4:7]) + + call s:close_windows() + finally + exe 'hi' save_hi + endtry +endfunc + +func Test_cursorline_highlight2() + CheckOption cursorlineopt + + let save_hi = s:new_hi() + try + call s:test_windows(10, 20) + call setline(1, repeat(['aaaa'], 10)) + redraw + let attr0 = s:screen_attr(1) + call assert_equal(repeat([attr0[0]], 8), attr0) + + setl number + redraw + let attr1 = s:screen_attr(1) + call assert_notequal(attr0[0:3], attr1[0:3]) + call assert_equal(attr0[0:3], attr1[4:7]) + + setl cursorline cursorlineopt=both + redraw + let attr2 = s:screen_attr(1) + call assert_notequal(attr1[0:3], attr2[0:3]) + call assert_notequal(attr1[4:7], attr2[4:7]) + + setl cursorlineopt=line + redraw + let attr3 = s:screen_attr(1) + call assert_equal(attr1[0:3], attr3[0:3]) + call assert_equal(attr2[4:7], attr3[4:7]) + + setl cursorlineopt=number + redraw + let attr4 = s:screen_attr(1) + call assert_equal(attr2[0:3], attr4[0:3]) + call assert_equal(attr1[4:7], attr4[4:7]) + + setl nonumber + redraw + let attr5 = s:screen_attr(1) + call assert_equal(attr0, attr5) + + call s:close_windows() + finally + exe 'hi' save_hi + endtry +endfunc + +func Test_cursorline_screenline() + CheckScreendump + CheckOption cursorlineopt + + let filename='Xcursorline' + let lines = [] + + let file_content =<< trim END + 1 foooooooo ar einszwei drei vier fünf sechs sieben acht un zehn elf zwöfl dreizehn v ierzehn fünfzehn + 2 foooooooo bar eins zwei drei vier fünf sechs sieben + 3 foooooooo bar eins zwei drei vier fünf sechs sieben + 4 foooooooo bar eins zwei drei vier fünf sechs sieben + END + let lines1 =<< trim END1 + set nocp + set display=lastline + set cursorlineopt=screenline cursorline nu wrap sbr=> + hi CursorLineNr ctermfg=blue + 25vsp + END1 + let lines2 =<< trim END2 + call cursor(1,1) + END2 + call extend(lines, lines1) + call extend(lines, ["call append(0, ".. string(file_content).. ')']) + call extend(lines, lines2) + call writefile(lines, filename) + " basic test + let buf = RunVimInTerminal('-S '. filename, #{rows: 20}) + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_1', {}) + call term_sendkeys(buf, "fagj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_2', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_3', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_4', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_5', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_6', {}) + " test with set list and cursorlineopt containing number + call term_sendkeys(buf, "gg0") + call term_sendkeys(buf, ":set list cursorlineopt+=number listchars=space:-\<cr>") + call VerifyScreenDump(buf, 'Test_'. filename. '_7', {}) + call term_sendkeys(buf, "fagj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_8', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_9', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_10', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_11', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_12', {}) + if exists("+foldcolumn") && exists("+signcolumn") && exists("+breakindent") + " test with set foldcolumn signcoloumn and breakindent + call term_sendkeys(buf, "gg0") + call term_sendkeys(buf, ":set breakindent foldcolumn=2 signcolumn=yes\<cr>") + call VerifyScreenDump(buf, 'Test_'. filename. '_13', {}) + call term_sendkeys(buf, "fagj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_14', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_15', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_16', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_17', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_18', {}) + endif + + call StopVimInTerminal(buf) + call delete(filename) +endfunc + +func Test_cursorline_redraw() + CheckScreendump + CheckOption cursorlineopt + + let textlines =<< END + When the option is a list of flags, {value} must be + exactly as they appear in the option. Remove flags + one by one to avoid problems. + Also see |:set-args| above. + +The {option} arguments to ":set" may be repeated. For example: > + :set ai nosi sw=3 ts=3 +If you make an error in one of the arguments, an error message will be given +and the following arguments will be ignored. + + *:set-verbose* +When 'verbose' is non-zero, displaying an option value will also tell where it +was last set. Example: > + :verbose set shiftwidth cindent? +< shiftwidth=4 ~ + Last set from modeline line 1 ~ + cindent ~ + Last set from /usr/local/share/vim/vim60/ftplugin/c.vim line 30 ~ +This is only done when specific option values are requested, not for ":verbose +set all" or ":verbose set" without an argument. +When the option was set by hand there is no "Last set" message. +When the option was set while executing a function, user command or +END + call writefile(textlines, 'Xtextfile') + + let script =<< trim END + set cursorline scrolloff=2 + normal 12G + END + call writefile(script, 'Xscript') + + let buf = RunVimInTerminal('-S Xscript Xtextfile', #{rows: 20, cols: 40}) + call VerifyScreenDump(buf, 'Test_cursorline_redraw_1', {}) + call term_sendkeys(buf, "zt") + call TermWait(buf) + call term_sendkeys(buf, "\<C-U>") + call VerifyScreenDump(buf, 'Test_cursorline_redraw_2', {}) + + call StopVimInTerminal(buf) + call delete('Xscript') + call delete('Xtextfile') +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index eb6151fbe1..4ab58cd084 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -192,6 +192,7 @@ let s:filename_checks = { \ 'gdb': ['.gdbinit'], \ 'gdmo': ['file.mo', 'file.gdmo'], \ 'gedcom': ['file.ged', 'lltxxxxx.txt', '/tmp/lltmp', '/tmp/lltmp-file', 'any/tmp/lltmp', 'any/tmp/lltmp-file'], + \ 'gemtext': ['file.gmi', 'file.gemini'], \ 'gift': ['file.gift'], \ 'gitcommit': ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG'], \ 'gitconfig': ['file.git/config', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig', '/etc/gitconfig.d/file', '/.gitconfig.d/file', 'any/.config/git/config', 'any/.gitconfig.d/file', 'some.git/config', 'some.git/modules/any/config'], @@ -260,6 +261,7 @@ let s:filename_checks = { \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'], \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'], \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'], + \ 'jsonc': ['file.jsonc'], \ 'jsp': ['file.jsp'], \ 'kconfig': ['Kconfig', 'Kconfig.debug', 'Kconfig.file'], \ 'kivy': ['file.kv'], @@ -429,6 +431,7 @@ let s:filename_checks = { \ 'scilab': ['file.sci', 'file.sce'], \ 'screen': ['.screenrc', 'screenrc'], \ 'sexplib': ['file.sexp'], + \ 'scdoc': ['file.scd'], \ 'scss': ['file.scss'], \ 'sd': ['file.sd'], \ 'sdc': ['file.sdc'], diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 224ca257ab..48f97be96b 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -534,6 +534,7 @@ func Test_mode() set complete=. inoremap <F2> <C-R>=Save_mode()<CR> + xnoremap <F2> <Cmd>call Save_mode()<CR> normal! 3G exe "normal i\<F2>\<Esc>" @@ -645,6 +646,14 @@ func Test_mode() call assert_equal("\<C-S>", mode(1)) call feedkeys("\<Esc>", 'xt') + " v_CTRL-O + exe "normal gh\<C-O>\<F2>\<Esc>" + call assert_equal("v-vs", g:current_modes) + exe "normal gH\<C-O>\<F2>\<Esc>" + call assert_equal("V-Vs", g:current_modes) + exe "normal g\<C-H>\<C-O>\<F2>\<Esc>" + call assert_equal("\<C-V>-\<C-V>s", g:current_modes) + call feedkeys(":echo \<C-R>=Save_mode()\<C-U>\<CR>", 'xt') call assert_equal('c-c', g:current_modes) call feedkeys("gQecho \<C-R>=Save_mode()\<CR>\<CR>vi\<CR>", 'xt') @@ -653,6 +662,7 @@ func Test_mode() bwipe! iunmap <F2> + xunmap <F2> set complete& endfunc @@ -996,6 +1006,9 @@ func Test_Executable() if catcmd =~ '\<sbin\>' && result =~ '\<bin\>' call assert_equal('/' .. substitute(catcmd, '\<sbin\>', 'bin', ''), result) else + " /bin/cat and /usr/bin/cat may be hard linked, we could get either + let result = substitute(result, '/usr/bin/cat', '/bin/cat', '') + let catcmd = substitute(catcmd, 'usr/bin/cat', 'bin/cat', '') call assert_equal('/' .. catcmd, result) endif bwipe @@ -1315,7 +1328,15 @@ endfunc func Test_getchar() call feedkeys('a', '') call assert_equal(char2nr('a'), getchar()) + call assert_equal(0, getchar(0)) + call assert_equal(0, getchar(1)) + + call feedkeys('a', '') + call assert_equal('a', getcharstr()) + call assert_equal('', getcharstr(0)) + call assert_equal('', getcharstr(1)) + call setline(1, 'xxxx') " call test_setmouse(1, 3) " let v:mouse_win = 9 " let v:mouse_winid = 9 @@ -1328,6 +1349,7 @@ func Test_getchar() call assert_equal(win_getid(1), v:mouse_winid) call assert_equal(1, v:mouse_lnum) call assert_equal(3, v:mouse_col) + enew! endfunc func Test_libcall_libcallnr() diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 4e46dbac16..fbe764bbf2 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -170,7 +170,7 @@ func Test_mksession_rtp() return endif new - set sessionoptions&vi + set sessionoptions+=options let _rtp=&rtp " Make a real long (invalid) runtimepath value, " that should exceed PATH_MAX (hopefully) @@ -287,10 +287,33 @@ func Test_mksession_blank_windows() call delete('Xtest_mks.out') endfunc +func Test_mksession_buffer_count() + set hidden + + " Edit exactly three files in the current session. + %bwipe! + e Xfoo | tabe Xbar | tabe Xbaz + tabdo write + mksession! Xtest_mks.out + + " Verify that loading the session does not create additional buffers. + %bwipe! + source Xtest_mks.out + call assert_equal(3, len(getbufinfo())) + + " Clean up. + call delete('Xfoo') + call delete('Xbar') + call delete('Xbaz') + call delete('Xtest_mks.out') + %bwipe! + set hidden& +endfunc + if has('extra_search') func Test_mksession_hlsearch() - set sessionoptions&vi + set sessionoptions+=options set hlsearch mksession! Xtest_mks.out nohlsearch @@ -630,7 +653,7 @@ endfunc " Test for mksession with a named scratch buffer func Test_mksession_scratch() - set sessionoptions&vi + set sessionoptions+=options enew | only file Xscratch set buftype=nofile diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 6bd64caa6c..5090584e41 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -134,6 +134,21 @@ func XlistTests(cchar) call assert_equal([' 2 Xtestfile1:1 col 3: Line1', \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) + " Ranged entries + call g:Xsetlist([{'lnum':10,'text':'Line1'}, + \ {'lnum':20,'col':10,'text':'Line2'}, + \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'}, + \ {'lnum':40,'end_lnum':45,'text':'Line4'}, + \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'}, + \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}]) + let l = split(execute('Xlist', ""), "\n") + call assert_equal([' 1:10: Line1', + \ ' 2:20 col 10: Line2', + \ ' 3:30 col 15-20: Line3', + \ ' 4:40-45: Line4', + \ ' 5:50-55 col 15: Line5', + \ ' 6:60-65 col 25-35: Line6'], l) + " Different types of errors call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11}, \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22}, @@ -599,6 +614,7 @@ func s:test_xhelpgrep(cchar) call assert_true(&buftype == 'help') call assert_true(winnr() == 1) call assert_true(winnr('$') == 2) + call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0]) " This wipes out the buffer, make sure that doesn't cause trouble. Xclose @@ -1437,10 +1453,13 @@ func SetXlistTests(cchar, bnum) call s:setup_commands(a:cchar) call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, - \ {'bufnr': a:bnum, 'lnum': 2}]) + \ {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}]) let l = g:Xgetlist() call assert_equal(2, len(l)) call assert_equal(2, l[1].lnum) + call assert_equal(3, l[1].end_lnum) + call assert_equal(4, l[1].col) + call assert_equal(5, l[1].end_col) Xnext call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a') @@ -2743,7 +2762,9 @@ func XvimgrepTests(cchar) let l = g:Xgetlist() call assert_equal(2, len(l)) call assert_equal(8, l[0].col) + call assert_equal(11, l[0].end_col) call assert_equal(12, l[1].col) + call assert_equal(15, l[1].end_col) 1Xvimgrep ?Editor? Xtestfile* let l = g:Xgetlist() @@ -2965,7 +2986,7 @@ func Test_cclose_in_autocmd() " call test_override('starting', 0) endfunc -" Check that ":file" without an argument is possible even when "curbuf_lock" +" Check that ":file" without an argument is possible even when curbuf is locked " is set. func Test_file_from_copen() " Works without argument. @@ -4850,7 +4871,42 @@ func Test_add_invalid_entry_with_qf_window() call setqflist(['bb'], 'a') call assert_equal(1, line('$')) call assert_equal(['Xfile1|10| aa'], getline(1, '$')) - call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist()) + call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': 0 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 0 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 0 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10 col 666| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': -456 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10 col 666-222| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': -123 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) + + call setqflist([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , 'r') + call assert_equal(1 , line('$')) + call assert_equal(['Xfile1|10-6 col 666-222| aa'] , getline(1 , '$')) + call assert_equal([{'lnum': 10 , 'end_lnum': 6 , 'bufnr': bufnr('Xfile1') , 'col': 666 , 'end_col': 222 , 'pattern': '' , 'valid': 1 , 'vcol': 0 , 'nr': -1 , 'type': '' , 'module': '' , 'text': 'aa'}] , getqflist()) cclose endfunc @@ -5001,15 +5057,21 @@ func Xtest_qftextfunc(cchar) call assert_equal('Tqfexpr', &quickfixtextfunc) call assert_equal('', \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc) - Xexpr ['F1:10:2:green', 'F1:20:4:blue'] + call g:Xsetlist([ + \ { 'filename': 'F1', 'lnum': 10, 'col': 2, + \ 'end_col': 7, 'text': 'green'}, + \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4, + \ 'end_col': 8, 'text': 'blue'}, + \ ]) + Xwindow call assert_equal('F1-L10C2-green', getline(1)) call assert_equal('F1-L20C4-blue', getline(2)) Xclose set quickfixtextfunc&vim Xwindow - call assert_equal('F1|10 col 2| green', getline(1)) - call assert_equal('F1|20 col 4| blue', getline(2)) + call assert_equal('F1|10 col 2-7| green', getline(1)) + call assert_equal('F1|20-25 col 4-8| blue', getline(2)) Xclose set efm& set quickfixtextfunc& @@ -5196,4 +5258,54 @@ func Test_qftextfunc_other_loclist() %bw! endfunc +func Test_locationlist_open_in_newtab() + call s:create_test_file('Xqftestfile1') + call s:create_test_file('Xqftestfile2') + call s:create_test_file('Xqftestfile3') + + %bwipe! + + lgetexpr ['Xqftestfile1:5:Line5', + \ 'Xqftestfile2:10:Line10', + \ 'Xqftestfile3:16:Line16'] + + silent! llast + call assert_equal(1, tabpagenr('$')) + call assert_equal('Xqftestfile3', bufname()) + + set switchbuf=newtab + + silent! lfirst + call assert_equal(2, tabpagenr('$')) + call assert_equal('Xqftestfile1', bufname()) + + silent! lnext + call assert_equal(3, tabpagenr('$')) + call assert_equal('Xqftestfile2', bufname()) + + call delete('Xqftestfile1') + call delete('Xqftestfile2') + call delete('Xqftestfile3') + set switchbuf&vim + + %bwipe! +endfunc + +" Test for win_gettype() in quickfix and location list windows +func Test_win_gettype() + copen + call assert_equal("quickfix", win_gettype()) + let wid = win_getid() + wincmd p + call assert_equal("quickfix", win_gettype(wid)) + cclose + lexpr '' + lopen + call assert_equal("loclist", win_gettype()) + let wid = win_getid() + wincmd p + call assert_equal("loclist", win_gettype(wid)) + lclose +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_spellfile.vim b/src/nvim/testdir/test_spellfile.vim index 729467b556..0f48ab8f6f 100644 --- a/src/nvim/testdir/test_spellfile.vim +++ b/src/nvim/testdir/test_spellfile.vim @@ -210,6 +210,52 @@ func Test_spellfile_CHECKCOMPOUNDPATTERN() call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl') endfunc +" Test NOCOMPOUNDSUGS (see :help spell-NOCOMPOUNDSUGS) +func Test_spellfile_NOCOMPOUNDSUGS() + call writefile(['3', + \ 'one/c', + \ 'two/c', + \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic') + + " pass 0 tests without NOCOMPOUNDSUGS, pass 1 tests with NOCOMPOUNDSUGS + for pass in [0, 1] + if pass == 0 + call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff') + else + call writefile(['NOCOMPOUNDSUGS', + \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff') + endif + + mkspell! XtestNOCOMPOUNDSUGS-utf8.spl XtestNOCOMPOUNDSUGS + set spell spelllang=XtestNOCOMPOUNDSUGS-utf8.spl + + for goodword in ['one', 'two', 'three', + \ 'oneone', 'onetwo', 'onethree', + \ 'twoone', 'twotwo', 'twothree', + \ 'threeone', 'threetwo', 'threethree', + \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone'] + call assert_equal(['', ''], spellbadword(goodword), goodword) + endfor + + for badword in ['four', 'onetwox', 'onexone'] + call assert_equal([badword, 'bad'], spellbadword(badword)) + endfor + + if pass == 0 + call assert_equal(['one', 'oneone'], spellsuggest('onne', 2)) + call assert_equal(['onethree', 'one three'], spellsuggest('onethre', 2)) + else + call assert_equal(['one', 'one one'], spellsuggest('onne', 2)) + call assert_equal(['one three'], spellsuggest('onethre', 2)) + endif + endfor + + set spell& spelllang& + call delete('XtestNOCOMPOUNDSUGS.dic') + call delete('XtestNOCOMPOUNDSUGS.aff') + call delete('XtestNOCOMPOUNDSUGS-utf8.spl') +endfunc + " Test COMMON (better suggestions with common words, see :help spell-COMMON) func Test_spellfile_COMMON() call writefile(['7', diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index f27920d20f..02bc297de1 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -319,6 +319,7 @@ func Test_swap_prompt_splitwin() let buf = RunVimInTerminal('', {'rows': 20}) call term_sendkeys(buf, ":set nomore\n") call term_sendkeys(buf, ":set noruler\n") + call term_sendkeys(buf, ":split Xfile1\n") call term_wait(buf) call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: $', term_getline(buf, 20))}) @@ -330,8 +331,19 @@ func Test_swap_prompt_splitwin() call term_wait(buf) call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))}) call StopVimInTerminal(buf) + + " This caused Vim to crash when typing "q". + " TODO: it does not actually reproduce the crash. + call writefile(['au BufAdd * set virtualedit=all'], 'Xvimrc') + + let buf = RunVimInTerminal('-u Xvimrc Xfile1', {'rows': 20, 'wait_for_ruler': 0}) + call TermWait(buf) + call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:', term_getline(buf, 20))}) + call term_sendkeys(buf, "q") + %bwipe! call delete('Xfile1') + call delete('Xvimrc') endfunc func Test_swap_symlink() @@ -364,4 +376,8 @@ func Test_swap_symlink() call delete('Xswapdir', 'rf') endfunc +func Test_no_swap_file() + call assert_equal("\nNo swap file", execute('swapname')) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 9f02af7d8e..68dcfb6890 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -771,15 +771,16 @@ func Test_ltag() ltag third call assert_equal('Xfoo', bufname('')) call assert_equal(3, line('.')) - call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0, - \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', - \ 'module': '', 'text': 'third'}], getloclist(0)) + call assert_equal([{'lnum': 3, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'), + \ 'col': 0, 'end_col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, + \ 'nr': 0, 'type': '', 'module': '', 'text': 'third'}], getloclist(0)) ltag second call assert_equal(2, line('.')) - call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0, - \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0, - \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0)) + call assert_equal([{'lnum': 0, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'), + \ 'col': 0, 'end_col': 0, 'pattern': '^\Vint second() {}\$', + \ 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'module': '', + \ 'text': 'second'}], getloclist(0)) call delete('Xtags') call delete('Xfoo') diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim index 4621207d19..29e578ac6d 100644 --- a/src/nvim/testdir/test_usercommands.vim +++ b/src/nvim/testdir/test_usercommands.vim @@ -238,6 +238,8 @@ func Test_CmdErrors() call assert_fails('com! -complete=custom DoCmd :', 'E467:') call assert_fails('com! -complete=customlist DoCmd :', 'E467:') call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:') + call assert_fails('com! -complete=file DoCmd :', 'E1208:') + call assert_fails('com! -nargs=0 -complete=file DoCmd :', 'E1208:') call assert_fails('com! -nargs=x DoCmd :', 'E176:') call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:') call assert_fails('com! -count=x DoCmd :', 'E178:') @@ -306,27 +308,33 @@ func Test_CmdCompletion() call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"com DoC', @:) - com! -complete=behave DoCmd : + com! -nargs=1 -complete=behave DoCmd : call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"DoCmd mswin xterm', @:) - " This does not work. Why? - "call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx') - "call assert_equal('"DoCmd xterm', @:) - - com! -complete=custom,CustomComplete DoCmd : + com! -nargs=* -complete=custom,CustomComplete DoCmd : call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"DoCmd January February Mars', @:) - com! -complete=customlist,CustomCompleteList DoCmd : + com! -nargs=? -complete=customlist,CustomCompleteList DoCmd : call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"DoCmd Monday Tuesday Wednesday', @:) - com! -complete=custom,CustomCompleteList DoCmd : + com! -nargs=+ -complete=custom,CustomCompleteList DoCmd : call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:') - com! -complete=customlist,CustomComp DoCmd : + com! -nargs=+ -complete=customlist,CustomComp DoCmd : call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:') + + " custom completion without a function + com! -nargs=? -complete=custom, DoCmd + call assert_beeps("call feedkeys(':DoCmd \t', 'tx')") + + " custom completion failure with the wrong function + com! -nargs=? -complete=custom,min DoCmd + call assert_fails("call feedkeys(':DoCmd \t', 'tx')", 'E118:') + + delcom DoCmd endfunc func CallExecute(A, L, P) @@ -459,21 +467,21 @@ func Test_command_list() \ execute('command DoCmd')) " Test with various -complete= argument values (non-exhaustive list) - command! -complete=arglist DoCmd : + command! -nargs=1 -complete=arglist DoCmd : call assert_equal("\n Name Args Address Complete Definition" - \ .. "\n DoCmd 0 arglist :", + \ .. "\n DoCmd 1 arglist :", \ execute('command DoCmd')) - command! -complete=augroup DoCmd : + command! -nargs=* -complete=augroup DoCmd : call assert_equal("\n Name Args Address Complete Definition" - \ .. "\n DoCmd 0 augroup :", + \ .. "\n DoCmd * augroup :", \ execute('command DoCmd')) - command! -complete=custom,CustomComplete DoCmd : + command! -nargs=? -complete=custom,CustomComplete DoCmd : call assert_equal("\n Name Args Address Complete Definition" - \ .. "\n DoCmd 0 custom :", + \ .. "\n DoCmd ? custom :", \ execute('command DoCmd')) - command! -complete=customlist,CustomComplete DoCmd : + command! -nargs=+ -complete=customlist,CustomComplete DoCmd : call assert_equal("\n Name Args Address Complete Definition" - \ .. "\n DoCmd 0 customlist :", + \ .. "\n DoCmd + customlist :", \ execute('command DoCmd')) " Test with various -narg= argument values. diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index b7c5717bd2..9c62bdb16e 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -2,6 +2,7 @@ source shared.vim source check.vim +source screendump.vim func Test_block_shift_multibyte() " Uses double-wide character. @@ -1082,5 +1083,25 @@ func Test_visual_put_blockedit_zy_and_zp() bw! endfunc +func Test_visual_block_with_virtualedit() + CheckScreendump + + let lines =<< trim END + call setline(1, ['aaaaaa', 'bbbb', 'cc']) + set virtualedit=block + normal G + END + call writefile(lines, 'XTest_block') + + let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50}) + call term_sendkeys(buf, "\<C-V>gg$") + call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {}) + + " clean up + call term_sendkeys(buf, "\<Esc>") + call StopVimInTerminal(buf) + call delete('XTest_beval') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 6e885279a9..dcc086a0cf 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1025,7 +1025,7 @@ static void tui_mouse_on(UI *ui) if (!data->mouse_enabled) { #ifdef WIN32 // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse traking of + // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of // libuv. For this reason, vtp (vterm) state of libuv is temporarily // disabled because the control sequence needs to be processed by libuv // instead of Windows vtp. @@ -1048,7 +1048,7 @@ static void tui_mouse_off(UI *ui) if (data->mouse_enabled) { #ifdef WIN32 // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse traking of + // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of // libuv. For this reason, vtp (vterm) state of libuv is temporarily // disabled because the control sequence needs to be processed by libuv // instead of Windows vtp. @@ -1123,8 +1123,8 @@ static void tui_mode_change(UI *ui, String mode, Integer mode_idx) data->showing_mode = (ModeShape)mode_idx; } -static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow, - Integer startcol, Integer endcol, +static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 + Integer endrow, Integer startcol, Integer endcol, Integer rows, Integer cols FUNC_ATTR_UNUSED) { TUIData *data = ui->data; diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index 1ec5189795..9c9aec1cf5 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -214,7 +214,7 @@ void ui_comp_remove_grid(ScreenGrid *grid) grid->comp_index = 0; // recompose the area under the grid - // inefficent when being overlapped: only draw up to grid->comp_index + // inefficient when being overlapped: only draw up to grid->comp_index ui_comp_compose_grid(grid); } @@ -594,7 +594,7 @@ static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, int first_row = MAX((int)row-(scrolled?1:0), 0); compose_area(first_row, Rows-delta, 0, Columns); } else { - // scroll separator togheter with message text + // scroll separator together with message text int first_row = MAX((int)row-(msg_was_scrolled?1:0), 0); ui_composed_call_grid_scroll(1, first_row, Rows, 0, Columns, delta, 0); if (scrolled && !msg_was_scrolled && row > 0) { diff --git a/src/nvim/undo.c b/src/nvim/undo.c index ffd613cec2..3096fe84c0 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -234,7 +234,7 @@ int u_save(linenr_T top, linenr_T bot) if (top + 2 == bot) u_saveline((linenr_T)(top + 1)); - return u_savecommon(top, bot, (linenr_T)0, FALSE); + return u_savecommon(curbuf, top, bot, (linenr_T)0, false); } /* @@ -245,7 +245,7 @@ int u_save(linenr_T top, linenr_T bot) */ int u_savesub(linenr_T lnum) { - return u_savecommon(lnum - 1, lnum + 1, lnum + 1, false); + return u_savecommon(curbuf, lnum - 1, lnum + 1, lnum + 1, false); } /* @@ -256,7 +256,7 @@ int u_savesub(linenr_T lnum) */ int u_inssub(linenr_T lnum) { - return u_savecommon(lnum - 1, lnum, lnum + 1, false); + return u_savecommon(curbuf, lnum - 1, lnum, lnum + 1, false); } /* @@ -268,18 +268,19 @@ int u_inssub(linenr_T lnum) */ int u_savedel(linenr_T lnum, long nlines) { - return u_savecommon(lnum - 1, lnum + nlines, - nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE); + return u_savecommon( + curbuf, lnum - 1, lnum + nlines, + nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, false); } /// Return true when undo is allowed. Otherwise print an error message and /// return false. /// /// @return true if undo is allowed. -bool undo_allowed(void) +bool undo_allowed(buf_T *buf) { - /* Don't allow changes when 'modifiable' is off. */ - if (!MODIFIABLE(curbuf)) { + // Don't allow changes when 'modifiable' is off. + if (!MODIFIABLE(buf)) { EMSG(_(e_modifiable)); return false; } @@ -301,12 +302,12 @@ bool undo_allowed(void) } /// Get the 'undolevels' value for the current buffer. -static long get_undolevel(void) +static long get_undolevel(buf_T *buf) { - if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) { + if (buf->b_p_ul == NO_LOCAL_UNDOLEVEL) { return p_ul; } - return curbuf->b_p_ul; + return buf->b_p_ul; } static inline void zero_fmark_additional_data(fmark_T *fmarks) @@ -326,7 +327,9 @@ static inline void zero_fmark_additional_data(fmark_T *fmarks) * Careful: may trigger autocommands that reload the buffer. * Returns FAIL when lines could not be saved, OK otherwise. */ -int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) +int u_savecommon(buf_T *buf, + linenr_T top, linenr_T bot, + linenr_T newbot, int reload) { linenr_T lnum; long i; @@ -337,22 +340,23 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) long size; if (!reload) { - /* When making changes is not allowed return FAIL. It's a crude way - * to make all change commands fail. */ - if (!undo_allowed()) + // When making changes is not allowed return FAIL. It's a crude way + // to make all change commands fail. + if (!undo_allowed(buf)) { return FAIL; + } + // Saving text for undo means we are going to make a change. Give a + // warning for a read-only file before making the change, so that the + // FileChangedRO event can replace the buffer with a read-write version + // (e.g., obtained from a source control system). + if (buf == curbuf) { + change_warning(buf, 0); + } - /* - * Saving text for undo means we are going to make a change. Give a - * warning for a read-only file before making the change, so that the - * FileChangedRO event can replace the buffer with a read-write version - * (e.g., obtained from a source control system). - */ - change_warning(0); - if (bot > curbuf->b_ml.ml_line_count + 1) { - /* This happens when the FileChangedRO autocommand changes the - * file in a way it becomes shorter. */ + if (bot > buf->b_ml.ml_line_count + 1) { + // This happens when the FileChangedRO autocommand changes the + // file in a way it becomes shorter. EMSG(_("E881: Line count changed unexpectedly")); return FAIL; } @@ -364,18 +368,14 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) size = bot - top - 1; - /* - * If curbuf->b_u_synced == true make a new header. - */ - if (curbuf->b_u_synced) { - /* Need to create new entry in b_changelist. */ - curbuf->b_new_change = true; - - if (get_undolevel() >= 0) { - /* - * Make a new header entry. Do this first so that we don't mess - * up the undo info when out of memory. - */ + // If curbuf->b_u_synced == true make a new header. + if (buf->b_u_synced) { + // Need to create new entry in b_changelist. + buf->b_new_change = true; + + if (get_undolevel(buf) >= 0) { + // Make a new header entry. Do this first so that we don't mess + // up the undo info when out of memory. uhp = xmalloc(sizeof(u_header_T)); kv_init(uhp->uh_extmark); #ifdef U_DEBUG @@ -388,63 +388,73 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) * If we undid more than we redid, move the entry lists before and * including curbuf->b_u_curhead to an alternate branch. */ - old_curhead = curbuf->b_u_curhead; + old_curhead = buf->b_u_curhead; if (old_curhead != NULL) { - curbuf->b_u_newhead = old_curhead->uh_next.ptr; - curbuf->b_u_curhead = NULL; + buf->b_u_newhead = old_curhead->uh_next.ptr; + buf->b_u_curhead = NULL; } /* * free headers to keep the size right */ - while (curbuf->b_u_numhead > get_undolevel() - && curbuf->b_u_oldhead != NULL) { - u_header_T *uhfree = curbuf->b_u_oldhead; - - if (uhfree == old_curhead) - /* Can't reconnect the branch, delete all of it. */ - u_freebranch(curbuf, uhfree, &old_curhead); - else if (uhfree->uh_alt_next.ptr == NULL) - /* There is no branch, only free one header. */ - u_freeheader(curbuf, uhfree, &old_curhead); - else { - /* Free the oldest alternate branch as a whole. */ - while (uhfree->uh_alt_next.ptr != NULL) + while (buf->b_u_numhead > get_undolevel(buf) + && buf->b_u_oldhead != NULL) { + u_header_T *uhfree = buf->b_u_oldhead; + + if (uhfree == old_curhead) { + // Can't reconnect the branch, delete all of it. + u_freebranch(buf, uhfree, &old_curhead); + } else if (uhfree->uh_alt_next.ptr == NULL) { + // There is no branch, only free one header. + u_freeheader(buf, uhfree, &old_curhead); + } else { + // Free the oldest alternate branch as a whole. + while (uhfree->uh_alt_next.ptr != NULL) { uhfree = uhfree->uh_alt_next.ptr; - u_freebranch(curbuf, uhfree, &old_curhead); + } + u_freebranch(buf, uhfree, &old_curhead); } #ifdef U_DEBUG u_check(TRUE); #endif } - if (uhp == NULL) { /* no undo at all */ - if (old_curhead != NULL) - u_freebranch(curbuf, old_curhead, NULL); - curbuf->b_u_synced = false; + if (uhp == NULL) { // no undo at all + if (old_curhead != NULL) { + u_freebranch(buf, old_curhead, NULL); + } + buf->b_u_synced = false; return OK; } uhp->uh_prev.ptr = NULL; - uhp->uh_next.ptr = curbuf->b_u_newhead; + uhp->uh_next.ptr = buf->b_u_newhead; uhp->uh_alt_next.ptr = old_curhead; if (old_curhead != NULL) { uhp->uh_alt_prev.ptr = old_curhead->uh_alt_prev.ptr; - if (uhp->uh_alt_prev.ptr != NULL) + + if (uhp->uh_alt_prev.ptr != NULL) { uhp->uh_alt_prev.ptr->uh_alt_next.ptr = uhp; + } + old_curhead->uh_alt_prev.ptr = uhp; - if (curbuf->b_u_oldhead == old_curhead) - curbuf->b_u_oldhead = uhp; - } else + + if (buf->b_u_oldhead == old_curhead) { + buf->b_u_oldhead = uhp; + } + } else { uhp->uh_alt_prev.ptr = NULL; - if (curbuf->b_u_newhead != NULL) - curbuf->b_u_newhead->uh_prev.ptr = uhp; + } + + if (buf->b_u_newhead != NULL) { + buf->b_u_newhead->uh_prev.ptr = uhp; + } - uhp->uh_seq = ++curbuf->b_u_seq_last; - curbuf->b_u_seq_cur = uhp->uh_seq; + uhp->uh_seq = ++buf->b_u_seq_last; + buf->b_u_seq_cur = uhp->uh_seq; uhp->uh_time = time(NULL); uhp->uh_save_nr = 0; - curbuf->b_u_time_cur = uhp->uh_time + 1; + buf->b_u_time_cur = uhp->uh_time + 1; uhp->uh_walk = 0; uhp->uh_entry = NULL; @@ -455,23 +465,26 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) else uhp->uh_cursor_vcol = -1; - /* save changed and buffer empty flag for undo */ - uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) + - ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0); + // save changed and buffer empty flag for undo + uhp->uh_flags = (buf->b_changed ? UH_CHANGED : 0) + + ((buf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0); + + // save named marks and Visual marks for undo + zero_fmark_additional_data(buf->b_namedm); + memmove(uhp->uh_namedm, buf->b_namedm, + sizeof(buf->b_namedm[0]) * NMARKS); + uhp->uh_visual = buf->b_visual; - /* save named marks and Visual marks for undo */ - zero_fmark_additional_data(curbuf->b_namedm); - memmove(uhp->uh_namedm, curbuf->b_namedm, - sizeof(curbuf->b_namedm[0]) * NMARKS); - uhp->uh_visual = curbuf->b_visual; + buf->b_u_newhead = uhp; - curbuf->b_u_newhead = uhp; - if (curbuf->b_u_oldhead == NULL) - curbuf->b_u_oldhead = uhp; - ++curbuf->b_u_numhead; + if (buf->b_u_oldhead == NULL) { + buf->b_u_oldhead = uhp; + } + buf->b_u_numhead++; } else { - if (get_undolevel() < 0) /* no undo at all */ + if (get_undolevel(buf) < 0) { // no undo at all return OK; + } /* * When saving a single line, and it has been saved just before, it @@ -483,7 +496,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) * long. */ if (size == 1) { - uep = u_get_headentry(); + uep = u_get_headentry(buf); prev_uep = NULL; for (i = 0; i < 10; ++i) { if (uep == NULL) @@ -491,16 +504,17 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) /* If lines have been inserted/deleted we give up. * Also when the line was included in a multi-line save. */ - if ((curbuf->b_u_newhead->uh_getbot_entry != uep + if ((buf->b_u_newhead->uh_getbot_entry != uep ? (uep->ue_top + uep->ue_size + 1 != (uep->ue_bot == 0 - ? curbuf->b_ml.ml_line_count + 1 + ? buf->b_ml.ml_line_count + 1 : uep->ue_bot)) - : uep->ue_lcount != curbuf->b_ml.ml_line_count) + : uep->ue_lcount != buf->b_ml.ml_line_count) || (uep->ue_size > 1 && top >= uep->ue_top - && top + 2 <= uep->ue_top + uep->ue_size + 1)) + && top + 2 <= uep->ue_top + uep->ue_size + 1)) { break; + } /* If it's the same line we can skip saving it again. */ if (uep->ue_size == 1 && uep->ue_top == top) { @@ -508,8 +522,8 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) /* It's not the last entry: get ue_bot for the last * entry now. Following deleted/inserted lines go to * the re-used entry. */ - u_getbot(); - curbuf->b_u_synced = false; + u_getbot(buf); + buf->b_u_synced = false; /* Move the found entry to become the last entry. The * order of undo/redo doesn't matter for the entries @@ -518,18 +532,18 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) * for the found entry if the line count is changed by * the executed command. */ prev_uep->ue_next = uep->ue_next; - uep->ue_next = curbuf->b_u_newhead->uh_entry; - curbuf->b_u_newhead->uh_entry = uep; + uep->ue_next = buf->b_u_newhead->uh_entry; + buf->b_u_newhead->uh_entry = uep; } - /* The executed command may change the line count. */ - if (newbot != 0) + // The executed command may change the line count. + if (newbot != 0) { uep->ue_bot = newbot; - else if (bot > curbuf->b_ml.ml_line_count) + } else if (bot > buf->b_ml.ml_line_count) { uep->ue_bot = 0; - else { - uep->ue_lcount = curbuf->b_ml.ml_line_count; - curbuf->b_u_newhead->uh_getbot_entry = uep; + } else { + uep->ue_lcount = buf->b_ml.ml_line_count; + buf->b_u_newhead->uh_getbot_entry = uep; } return OK; } @@ -538,8 +552,8 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) } } - /* find line number for ue_bot for previous u_save() */ - u_getbot(); + // find line number for ue_bot for previous u_save() + u_getbot(buf); } /* @@ -553,17 +567,15 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) uep->ue_size = size; uep->ue_top = top; - if (newbot != 0) + if (newbot != 0) { uep->ue_bot = newbot; - /* - * Use 0 for ue_bot if bot is below last line. - * Otherwise we have to compute ue_bot later. - */ - else if (bot > curbuf->b_ml.ml_line_count) + // Use 0 for ue_bot if bot is below last line. + // Otherwise we have to compute ue_bot later. + } else if (bot > buf->b_ml.ml_line_count) { uep->ue_bot = 0; - else { - uep->ue_lcount = curbuf->b_ml.ml_line_count; - curbuf->b_u_newhead->uh_getbot_entry = uep; + } else { + uep->ue_lcount = buf->b_ml.ml_line_count; + buf->b_u_newhead->uh_getbot_entry = uep; } if (size > 0) { @@ -574,17 +586,19 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) u_freeentry(uep, i); return FAIL; } - uep->ue_array[i] = u_save_line(lnum++); + uep->ue_array[i] = u_save_line_buf(buf, lnum++); } - } else + } else { uep->ue_array = NULL; - uep->ue_next = curbuf->b_u_newhead->uh_entry; - curbuf->b_u_newhead->uh_entry = uep; + } + + uep->ue_next = buf->b_u_newhead->uh_entry; + buf->b_u_newhead->uh_entry = uep; if (reload) { // buffer was reloaded, notify text change subscribers curbuf->b_u_newhead->uh_flags |= UH_RELOAD; } - curbuf->b_u_synced = false; + buf->b_u_synced = false; undo_undoes = false; #ifdef U_DEBUG @@ -617,18 +631,20 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s"); -/* - * Compute the hash for the current buffer text into hash[UNDO_HASH_SIZE]. - */ -void u_compute_hash(char_u *hash) +/// Compute the hash for a buffer text into hash[UNDO_HASH_SIZE]. +/// +/// @param[in] buf The buffer used to compute the hash +/// @param[in] hash Array of size UNDO_HASH_SIZE in which to store the value of +/// the hash +void u_compute_hash(buf_T *buf, char_u *hash) { context_sha256_T ctx; linenr_T lnum; char_u *p; sha256_start(&ctx); - for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) { - p = ml_get(lnum); + for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) { + p = ml_get_buf(buf, lnum, false); sha256_update(&ctx, p, (uint32_t)(STRLEN(p) + 1)); } sha256_finish(&ctx, hash); @@ -1002,14 +1018,14 @@ static ExtmarkUndoObject *unserialize_extmark(bufinfo_T *bi, bool *error, extup->type = type; if (type == kExtmarkSplice) { n_elems = (size_t)sizeof(ExtmarkSplice) / sizeof(uint8_t); - buf = xcalloc(sizeof(uint8_t), n_elems); + buf = xcalloc(n_elems, sizeof(uint8_t)); if (!undo_read(bi, buf, n_elems)) { goto error; } extup->data.splice = *(ExtmarkSplice *)buf; } else if (type == kExtmarkMove) { n_elems = (size_t)sizeof(ExtmarkMove) / sizeof(uint8_t); - buf = xcalloc(sizeof(uint8_t), n_elems); + buf = xcalloc(n_elems, sizeof(uint8_t)); if (!undo_read(bi, buf, n_elems)) { goto error; } @@ -1846,8 +1862,9 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) { int count = startcount; - if (!undo_allowed()) + if (!undo_allowed(curbuf)) { return; + } u_newcount = 0; u_oldcount = 0; @@ -1858,15 +1875,16 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) * needed. This may cause the file to be reloaded, that must happen * before we do anything, because it may change curbuf->b_u_curhead * and more. */ - change_warning(0); + change_warning(curbuf, 0); if (undo_undoes) { - if (curbuf->b_u_curhead == NULL) /* first undo */ + if (curbuf->b_u_curhead == NULL) { // first undo curbuf->b_u_curhead = curbuf->b_u_newhead; - else if (get_undolevel() > 0) /* multi level undo */ - /* get next undo */ + } else if (get_undolevel(curbuf) > 0) { // multi level undo + // get next undo curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr; - /* nothing to undo */ + } + // nothing to undo if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) { /* stick curbuf->b_u_curhead at end */ curbuf->b_u_curhead = curbuf->b_u_oldhead; @@ -1880,8 +1898,8 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) u_undoredo(true, do_buf_event); } else { - if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) { - beep_flush(); /* nothing to redo */ + if (curbuf->b_u_curhead == NULL || get_undolevel(curbuf) <= 0) { + beep_flush(); // nothing to redo if (count == startcount - 1) { MSG(_("Already at newest change")); return; @@ -2122,8 +2140,8 @@ target_zero: if (uhp != NULL || target == 0) { // First go up the tree as much as needed. while (!got_int) { - /* Do the change warning now, for the same reason as above. */ - change_warning(0); + // Do the change warning now, for the same reason as above. + change_warning(curbuf, 0); uhp = curbuf->b_u_curhead; if (uhp == NULL) @@ -2147,7 +2165,7 @@ target_zero: // And now go down the tree (redo), branching off where needed. while (!got_int) { // Do the change warning now, for the same reason as above. - change_warning(0); + change_warning(curbuf, 0); uhp = curbuf->b_u_curhead; if (uhp == NULL) { @@ -2414,7 +2432,7 @@ static void u_undoredo(int undo, bool do_buf_event) curhead->uh_entry = newlist; curhead->uh_flags = new_flags; - if ((old_flags & UH_EMPTYBUF) && BUFEMPTY()) { + if ((old_flags & UH_EMPTYBUF) && buf_is_empty(curbuf)) { curbuf->b_ml.ml_flags |= ML_EMPTY; } if (old_flags & UH_CHANGED) { @@ -2591,13 +2609,15 @@ u_sync( int force // Also sync when no_u_sync is set. ) { - /* Skip it when already synced or syncing is disabled. */ - if (curbuf->b_u_synced || (!force && no_u_sync > 0)) + // Skip it when already synced or syncing is disabled. + if (curbuf->b_u_synced || (!force && no_u_sync > 0)) { return; - if (get_undolevel() < 0) - curbuf->b_u_synced = true; /* no entries, nothing to do */ - else { - u_getbot(); /* compute ue_bot of previous u_save */ + } + + if (get_undolevel(curbuf) < 0) { + curbuf->b_u_synced = true; // no entries, nothing to do + } else { + u_getbot(curbuf); // compute ue_bot of previous u_save curbuf->b_u_curhead = NULL; } } @@ -2708,7 +2728,7 @@ void ex_undojoin(exarg_T *eap) if (!curbuf->b_u_synced) { return; // already unsynced } - if (get_undolevel() < 0) { + if (get_undolevel(curbuf) < 0) { return; // no entries, nothing to do } else { curbuf->b_u_synced = false; // Append next change to last entry @@ -2792,38 +2812,39 @@ static void u_unch_branch(u_header_T *uhp) * Get pointer to last added entry. * If it's not valid, give an error message and return NULL. */ -static u_entry_T *u_get_headentry(void) +static u_entry_T *u_get_headentry(buf_T *buf) { - if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) { + if (buf->b_u_newhead == NULL || buf->b_u_newhead->uh_entry == NULL) { IEMSG(_("E439: undo list corrupt")); return NULL; } - return curbuf->b_u_newhead->uh_entry; + return buf->b_u_newhead->uh_entry; } /* * u_getbot(): compute the line number of the previous u_save * It is called only when b_u_synced is false. */ -static void u_getbot(void) +static void u_getbot(buf_T *buf) { u_entry_T *uep; linenr_T extra; - uep = u_get_headentry(); /* check for corrupt undo list */ - if (uep == NULL) + uep = u_get_headentry(buf); // check for corrupt undo list + if (uep == NULL) { return; + } - uep = curbuf->b_u_newhead->uh_getbot_entry; + uep = buf->b_u_newhead->uh_getbot_entry; if (uep != NULL) { /* * the new ue_bot is computed from the number of lines that has been * inserted (0 - deleted) since calling u_save. This is equal to the * old line count subtracted from the current line count. */ - extra = curbuf->b_ml.ml_line_count - uep->ue_lcount; + extra = buf->b_ml.ml_line_count - uep->ue_lcount; uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra; - if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) { + if (uep->ue_bot < 1 || uep->ue_bot > buf->b_ml.ml_line_count) { IEMSG(_("E440: undo line missing")); uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will // get all the old lines back @@ -2831,10 +2852,10 @@ static void u_getbot(void) // ones } - curbuf->b_u_newhead->uh_getbot_entry = NULL; + buf->b_u_newhead->uh_getbot_entry = NULL; } - curbuf->b_u_synced = true; + buf->b_u_synced = true; } /* @@ -3014,10 +3035,12 @@ void u_undoline(void) return; } - /* first save the line for the 'u' command */ - if (u_savecommon(curbuf->b_u_line_lnum - 1, - curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL) + // first save the line for the 'u' command + if (u_savecommon(curbuf, curbuf->b_u_line_lnum - 1, + curbuf->b_u_line_lnum + 1, (linenr_T)0, false) == FAIL) { return; + } + oldp = u_save_line(curbuf->b_u_line_lnum); ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true); changed_bytes(curbuf->b_u_line_lnum, 0); @@ -3048,12 +3071,21 @@ void u_blockfree(buf_T *buf) xfree(buf->b_u_line_ptr); } -/* - * u_save_line(): allocate memory and copy line 'lnum' into it. - */ +/// Allocate memory and copy curbuf line into it. +/// +/// @param lnum the line to copy static char_u *u_save_line(linenr_T lnum) { - return vim_strsave(ml_get(lnum)); + return u_save_line_buf(curbuf, lnum); +} + +/// Allocate memory and copy line into it +/// +/// @param lnum line to copy +/// @param buf buffer to copy from +static char_u *u_save_line_buf(buf_T *buf, linenr_T lnum) +{ + return vim_strsave(ml_get_buf(buf, lnum, false)); } /// Check if the 'modified' flag is set, or 'ff' has changed (only need to @@ -3143,18 +3175,16 @@ u_header_T *u_force_get_undo_header(buf_T *buf) if (!uhp) { // Undo is normally invoked in change code, which already has swapped // curbuf. - buf_T *save_curbuf = curbuf; - curbuf = buf; // Args are tricky: this means replace empty range by empty range.. - u_savecommon(0, 1, 1, true); + u_savecommon(curbuf, 0, 1, 1, true); + uhp = buf->b_u_curhead; if (!uhp) { uhp = buf->b_u_newhead; - if (get_undolevel() > 0 && !uhp) { + if (get_undolevel(curbuf) > 0 && !uhp) { abort(); } } - curbuf = save_curbuf; } return uhp; } diff --git a/src/nvim/version.c b/src/nvim/version.c index f3a30630f8..48ef71613e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -13,6 +13,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/buffer.h" #include "nvim/iconv.h" #include "nvim/version.h" #include "nvim/charset.h" @@ -2190,7 +2191,7 @@ void list_version(void) /// Show the intro message when not editing a file. void maybe_intro_message(void) { - if (BUFEMPTY() + if (buf_is_empty(curbuf) && (curbuf->b_fname == NULL) && (firstwin->w_next == NULL) && (vim_strchr(p_shm, SHM_INTRO) == NULL)) { diff --git a/src/nvim/vim.h b/src/nvim/vim.h index df4ab04eb6..c719c064e2 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -270,7 +270,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() /// On some systems case in a file name does not matter, on others it does. /// /// @note Does not account for maximum name lengths and things like "../dir", -/// thus it is not 100% accurate. OS may also use different algorythm for +/// thus it is not 100% accurate. OS may also use different algorithm for /// case-insensitive comparison. /// /// @param[in] x First file name to compare. diff --git a/src/nvim/window.c b/src/nvim/window.c index d051e8e467..fe6ab5af55 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -31,6 +31,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/file_search.h" #include "nvim/garray.h" #include "nvim/move.h" @@ -676,7 +677,7 @@ void win_set_minimal_style(win_T *wp) } // signcolumn: use 'auto' - if (wp->w_p_scl[0] != 'a') { + if (wp->w_p_scl[0] != 'a' || STRLEN(wp->w_p_scl) >= 8) { xfree(wp->w_p_scl); wp->w_p_scl = (char_u *)xstrdup("auto"); } @@ -2275,8 +2276,8 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, * Don't trigger autocommands yet, they may use wrong values, so do * that below. */ - goto_tabpage_tp(alt_tabpage(), FALSE, TRUE); - redraw_tabline = TRUE; + goto_tabpage_tp(alt_tabpage(), false, true); + redraw_tabline = true; // save index for tabclosed event char_u prev_idx[NUMBUFLEN]; @@ -3834,18 +3835,15 @@ int tabpage_index(tabpage_T *ftp) return i; } -/* - * Prepare for leaving the current tab page. - * When autocommands change "curtab" we don't leave the tab page and return - * FAIL. - * Careful: When OK is returned need to get a new tab page very very soon! - */ -static int -leave_tabpage ( - buf_T *new_curbuf, /* what is going to be the new curbuf, - NULL if unknown */ - int trigger_leave_autocmds -) +/// Prepare for leaving the current tab page. +/// When autocommands change "curtab" we don't leave the tab page and return +/// FAIL. +/// Careful: When OK is returned need to get a new tab page very very soon! +/// +/// @param new_curbuf what is going to be the new curbuf, +/// NULL if unknown. +/// @param trigger_leave_autocmds when true trigger *Leave autocommands. +static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) { tabpage_T *tp = curtab; @@ -3874,13 +3872,14 @@ leave_tabpage ( return OK; } -/* - * Start using tab page "tp". - * Only to be used after leave_tabpage() or freeing the current tab page. - * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE. - * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE. - */ -static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_autocmds, int trigger_leave_autocmds) +/// Start using tab page "tp". +/// Only to be used after leave_tabpage() or freeing the current tab page. +/// +/// @param trigger_enter_autocmds when true trigger *Enter autocommands. +/// @param trigger_leave_autocmds when true trigger *Leave autocommands. +static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, + bool trigger_enter_autocmds, + bool trigger_leave_autocmds) { int old_off = tp->tp_firstwin->w_winrow; win_T *next_prevwin = tp->tp_prevwin; @@ -4023,17 +4022,16 @@ void goto_tabpage(int n) } } - goto_tabpage_tp(tp, TRUE, TRUE); - + goto_tabpage_tp(tp, true, true); } -/* - * Go to tabpage "tp". - * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE. - * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE. - * Note: doesn't update the GUI tab. - */ -void goto_tabpage_tp(tabpage_T *tp, int trigger_enter_autocmds, int trigger_leave_autocmds) +/// Go to tabpage "tp". +/// Note: doesn't update the GUI tab. +/// +/// @param trigger_enter_autocmds when true trigger *Enter autocommands. +/// @param trigger_leave_autocmds when true trigger *Leave autocommands. +void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, + bool trigger_leave_autocmds) { /* Don't repeat a message in another tab page. */ set_keep_msg(NULL, 0); @@ -4064,7 +4062,7 @@ void goto_tabpage_lastused(void) */ void goto_tabpage_win(tabpage_T *tp, win_T *wp) { - goto_tabpage_tp(tp, TRUE, TRUE); + goto_tabpage_tp(tp, true, true); if (curtab == tp && win_valid(wp)) { win_enter(wp, true); } @@ -4120,8 +4118,8 @@ void tabpage_move(int nr) tp_dst->tp_next = curtab; } - /* Need to redraw the tabline. Tab page contents doesn't change. */ - redraw_tabline = TRUE; + // Need to redraw the tabline. Tab page contents doesn't change. + redraw_tabline = true; } @@ -4350,8 +4348,8 @@ void win_enter(win_T *wp, bool undo_sync) * been closed and isn't valid. */ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, - int trigger_new_autocmds, int trigger_enter_autocmds, - int trigger_leave_autocmds) + int trigger_new_autocmds, bool trigger_enter_autocmds, + bool trigger_leave_autocmds) { int other_buffer = FALSE; @@ -4665,8 +4663,10 @@ win_free ( // If there already is an entry with "wi_win" set to NULL it // must be removed, it would never be used. + // Skip "wip" itself, otherwise Coverity complains. for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) { - if (wip2->wi_win == NULL) { + // `wip2 != wip` to satisfy Coverity. #14884 + if (wip2 != wip && wip2->wi_win == NULL) { if (wip2->wi_next != NULL) { wip2->wi_next->wi_prev = wip2->wi_prev; } @@ -5906,13 +5906,13 @@ void command_height(void) grid_fill(&default_grid, cmdline_row, Rows, 0, Columns, ' ', ' ', 0); } msg_row = cmdline_row; - redraw_cmdline = TRUE; + redraw_cmdline = true; return; } if (msg_row < cmdline_row) msg_row = cmdline_row; - redraw_cmdline = TRUE; + redraw_cmdline = true; } frame_add_height(frp, (int)(old_p_ch - p_ch)); @@ -6433,8 +6433,9 @@ int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, curtab = tp; firstwin = curtab->tp_firstwin; lastwin = curtab->tp_lastwin; - } else - goto_tabpage_tp(tp, FALSE, FALSE); + } else { + goto_tabpage_tp(tp, false, false); + } } if (!win_valid(win)) { return FAIL; @@ -6464,8 +6465,9 @@ void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, curtab = save_curtab; firstwin = curtab->tp_firstwin; lastwin = curtab->tp_lastwin; - } else - goto_tabpage_tp(save_curtab, FALSE, FALSE); + } else { + goto_tabpage_tp(save_curtab, false, false); + } } if (win_valid(save_curwin)) { curwin = save_curwin; |