From 8e97edb93f01a08b332289405f83624cfb067fcc Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Mon, 22 May 2023 16:57:30 +0200 Subject: fix(extmark): restore extmarks when completing original text --- src/nvim/extmark.c | 13 +++++++------ src/nvim/insexpand.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index d9c1993f32..f510845ec7 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -311,9 +311,8 @@ void extmark_free_all(buf_T *buf) /// copying is useful when we cannot simply reverse the operation. This will do /// nothing on redo, enforces correct position when undo. void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, colnr_T u_col, - ExtmarkOp op) + extmark_undo_vec_t *uvp, bool only_copy, ExtmarkOp op) { - u_header_T *uhp = u_force_get_undo_header(buf); MarkTreeIter itr[1] = { 0 }; ExtmarkUndoObject undo; @@ -328,7 +327,7 @@ void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, coln bool invalidated = false; // Invalidate/delete mark - if (!mt_invalid(mark) && mt_invalidate(mark) && !mt_end(mark)) { + if (!only_copy && !mt_invalid(mark) && mt_invalidate(mark) && !mt_end(mark)) { MTPos endpos = marktree_get_altpos(buf->b_marktree, mark, NULL); if (endpos.row < 0) { endpos = mark.pos; @@ -348,7 +347,7 @@ void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, coln } // Push mark to undo header - if (uhp && op == kExtmarkUndo && !mt_no_undo(mark)) { + if (only_copy || (uvp != NULL && op == kExtmarkUndo && !mt_no_undo(mark))) { ExtmarkSavePos pos; pos.mark = mt_lookup_key(mark); pos.invalidated = invalidated; @@ -359,7 +358,7 @@ void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, coln undo.data.savepos = pos; undo.type = kExtmarkSavePos; - kv_push(uhp->uh_extmark, undo); + kv_push(*uvp, undo); } marktree_itr_next(buf->b_marktree, itr); @@ -511,7 +510,9 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t // merge!) int end_row = start_row + old_row; int end_col = (old_row ? 0 : start_col) + old_col; - extmark_splice_delete(buf, start_row, start_col, end_row, end_col, undo); + u_header_T *uhp = u_force_get_undo_header(buf); + extmark_undo_vec_t *uvp = uhp ? &uhp->uh_extmark : NULL; + extmark_splice_delete(buf, start_row, start_col, end_row, end_col, uvp, false, undo); } // Move the signcolumn sentinel line diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 12543a2d42..728277e5a3 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -23,6 +23,7 @@ #include "nvim/eval/userfunc.h" #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" +#include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" #include "nvim/garray.h" @@ -252,6 +253,8 @@ static colnr_T compl_col = 0; ///< column where the text starts ///< that is being completed static char *compl_orig_text = NULL; ///< text as it was before ///< completion started +/// Undo information to restore extmarks for original text. +static extmark_undo_vec_t compl_orig_extmarks; static int compl_cont_mode = 0; static expand_T compl_xp; @@ -1569,6 +1572,7 @@ void ins_compl_clear(void) XFREE_CLEAR(compl_pattern); XFREE_CLEAR(compl_leader); edit_submode_extra = NULL; + kv_destroy(compl_orig_extmarks); XFREE_CLEAR(compl_orig_text); compl_enter_selects = false; // clear v:completed_item @@ -2019,6 +2023,7 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval) ins_bytes_len(p + compl_len, (size_t)(len - compl_len)); } } + restore_orig_extmarks(); retval = true; } @@ -2505,6 +2510,22 @@ static void ins_compl_add_dict(dict_T *dict) } } +/// Save extmarks in "compl_orig_text" so that they may be restored when the +/// completion is cancelled, or the original text is completed. +static void save_orig_extmarks(void) +{ + extmark_splice_delete(curbuf, curwin->w_cursor.lnum - 1, compl_col, curwin->w_cursor.lnum - 1, + compl_col + compl_length, &compl_orig_extmarks, true, kExtmarkUndo); +} + +static void restore_orig_extmarks(void) +{ + for (long i = (int)kv_size(compl_orig_extmarks) - 1; i > -1; i--) { + ExtmarkUndoObject undo_info = kv_A(compl_orig_extmarks, i); + extmark_apply_undo(undo_info, true); + } +} + /// Start completion for the complete() function. /// /// @param startcol where the matched text starts (1 is first column). @@ -2526,10 +2547,10 @@ static void set_completion(colnr_T startcol, list_T *list) startcol = curwin->w_cursor.col; } compl_col = startcol; - compl_length = (int)curwin->w_cursor.col - (int)startcol; + compl_length = curwin->w_cursor.col - startcol; // compl_pattern doesn't need to be set - compl_orig_text = xstrnsave(get_cursor_line_ptr() + compl_col, - (size_t)compl_length); + compl_orig_text = xstrnsave(get_cursor_line_ptr() + compl_col, (size_t)compl_length); + save_orig_extmarks(); if (p_ic) { flags |= CP_ICASE; } @@ -3689,12 +3710,16 @@ static int ins_compl_next(bool allow_get_expansion, int count, bool insert_match if (compl_no_insert && !started) { ins_bytes(compl_orig_text + get_compl_len()); compl_used_match = false; + restore_orig_extmarks(); } else if (insert_match) { if (!compl_get_longest || compl_used_match) { ins_compl_insert(in_compl_func); } else { ins_bytes(compl_leader + get_compl_len()); } + if (!strcmp(compl_curr_match->cp_str, compl_orig_text)) { + restore_orig_extmarks(); + } } else { compl_used_match = false; } @@ -4267,7 +4292,9 @@ static int ins_compl_start(void) // Always add completion for the original text. xfree(compl_orig_text); + kv_destroy(compl_orig_extmarks); compl_orig_text = xstrnsave(line + compl_col, (size_t)compl_length); + save_orig_extmarks(); int flags = CP_ORIGINAL_TEXT; if (p_ic) { flags |= CP_ICASE; @@ -4276,6 +4303,7 @@ static int ins_compl_start(void) flags, false) != OK) { XFREE_CLEAR(compl_pattern); XFREE_CLEAR(compl_orig_text); + kv_destroy(compl_orig_extmarks); return FAIL; } @@ -4508,6 +4536,7 @@ static unsigned quote_meta(char *dest, char *src, int len) void free_insexpand_stuff(void) { XFREE_CLEAR(compl_orig_text); + kv_destroy(compl_orig_extmarks); callback_free(&cfu_cb); callback_free(&ofu_cb); callback_free(&tsrfu_cb); -- cgit From 5ca6c9e04629fee4e9f1f9786e9d36a2f892160c Mon Sep 17 00:00:00 2001 From: Luki446 Date: Sat, 11 Nov 2023 22:32:08 +0100 Subject: fix(terminal): make backslashes in 'shell' work on Windows If backslashes are used in 'shell' option, escape them to make Terminal mode work. --- src/nvim/ex_docmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0b466bbe4e..245121f4af 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7424,7 +7424,9 @@ static void ex_terminal(exarg_T *eap) char shell_argv[512] = { 0 }; while (*p != NULL) { - snprintf(tempstring, sizeof(tempstring), ",\"%s\"", *p); + char *escaped = vim_strsave_escaped(*p, "\"\\"); + snprintf(tempstring, sizeof(tempstring), ",\"%s\"", escaped); + xfree(escaped); xstrlcat(shell_argv, tempstring, sizeof(shell_argv)); p++; } -- cgit From 543e0256c19f397921a332e06b423215fd9aecb5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 15:51:05 +0800 Subject: build: don't define FUNC_ATTR_* as empty in headers (#26317) FUNC_ATTR_* should only be used in .c files with generated headers. Defining FUNC_ATTR_* as empty in headers causes misuses of them to be silently ignored. Instead don't define them by default, and only define them as empty after a .c file has included its generated header. --- src/klib/kvec.h | 4 +++- src/nvim/CMakeLists.txt | 2 +- src/nvim/api/autocmd.c | 1 - src/nvim/api/buffer.c | 1 - src/nvim/api/command.c | 1 - src/nvim/api/deprecated.c | 1 - src/nvim/api/extmark.c | 1 - src/nvim/api/options.c | 1 - src/nvim/api/private/converter.c | 1 - src/nvim/api/private/helpers.c | 1 - src/nvim/api/tabpage.c | 5 ++++- src/nvim/api/ui.c | 1 - src/nvim/api/vim.c | 1 - src/nvim/api/vimscript.c | 1 - src/nvim/api/win_config.c | 1 - src/nvim/api/window.c | 5 ++++- src/nvim/arabic.c | 1 - src/nvim/arglist.c | 1 - src/nvim/ascii_defs.h | 4 ++++ src/nvim/autocmd.c | 1 - src/nvim/base64.c | 5 +++-- src/nvim/buffer_updates.c | 3 +-- src/nvim/bufwrite.c | 1 - src/nvim/change.c | 1 - src/nvim/channel.h | 8 ++++++-- src/nvim/cmdexpand.c | 1 - src/nvim/cmdhist.c | 1 - src/nvim/context.c | 1 - src/nvim/cursor_shape.c | 1 - src/nvim/debugger.c | 1 - src/nvim/diff.c | 1 - src/nvim/digraph.c | 1 - src/nvim/drawscreen.c | 1 - src/nvim/edit.c | 3 +-- src/nvim/eval.c | 1 - src/nvim/eval/buffer.c | 1 - src/nvim/eval/decode.c | 1 - src/nvim/eval/encode.h | 4 +++- src/nvim/eval/executor.c | 3 +-- src/nvim/eval/funcs.c | 1 - src/nvim/eval/typval.h | 12 ++++++------ src/nvim/eval/userfunc.c | 1 - src/nvim/eval/vars.c | 1 - src/nvim/event/libuv_process.c | 1 - src/nvim/event/multiqueue.c | 1 - src/nvim/event/process.c | 1 - src/nvim/event/rstream.c | 1 - src/nvim/event/signal.c | 1 - src/nvim/event/socket.c | 1 - src/nvim/event/stream.c | 1 - src/nvim/event/time.c | 1 - src/nvim/event/wstream.c | 1 - src/nvim/ex_cmds.c | 1 - src/nvim/ex_docmd.c | 1 - src/nvim/ex_eval.c | 1 - src/nvim/ex_getln.c | 1 - src/nvim/ex_session.c | 1 - src/nvim/fileio.c | 1 - src/nvim/fold.c | 1 - src/nvim/func_attr.h | 27 +++++++++++---------------- src/nvim/garray.c | 3 +-- src/nvim/generators/gen_api_dispatch.lua | 4 ++-- src/nvim/generators/gen_declarations.lua | 30 ++++++++++++++++++------------ src/nvim/getchar.c | 1 - src/nvim/hashtab.c | 1 - src/nvim/help.c | 1 - src/nvim/highlight_group.c | 1 - src/nvim/indent.c | 1 - src/nvim/indent_c.c | 1 - src/nvim/insexpand.c | 1 - src/nvim/keycodes.c | 1 - src/nvim/lib/queue.h | 26 ++++++++++++++++++++------ src/nvim/log.c | 1 - src/nvim/lua/converter.c | 1 - src/nvim/lua/stdlib.c | 1 - src/nvim/main.c | 1 - src/nvim/mapping.c | 3 +-- src/nvim/mark.h | 8 ++++++-- src/nvim/match.c | 1 - src/nvim/math.c | 5 ++++- src/nvim/memline.c | 1 - src/nvim/memory.c | 1 - src/nvim/menu.c | 1 - src/nvim/message.c | 1 - src/nvim/mouse.c | 1 - src/nvim/move.c | 1 - src/nvim/msgpack_rpc/channel.c | 1 - src/nvim/msgpack_rpc/helpers.c | 1 - src/nvim/msgpack_rpc/server.c | 1 - src/nvim/normal.c | 1 - src/nvim/ops.h | 8 ++++++-- src/nvim/option.c | 1 - src/nvim/optionstr.c | 1 - src/nvim/os/env.c | 5 ++++- src/nvim/os/fs.c | 1 - src/nvim/os/input.c | 1 - src/nvim/os/process.c | 3 ++- src/nvim/os/pty_process_unix.c | 1 - src/nvim/os/shell.c | 1 - src/nvim/os/signal.c | 1 - src/nvim/os/stdpaths.c | 5 ++++- src/nvim/os/time.c | 3 +-- src/nvim/os/users.c | 4 ++++ src/nvim/path.c | 2 +- src/nvim/plines.c | 1 - src/nvim/profile.c | 1 - src/nvim/quickfix.c | 1 - src/nvim/rbuffer.c | 5 ++--- src/nvim/regexp.c | 1 - src/nvim/runtime.c | 1 - src/nvim/search.c | 1 - src/nvim/shada.c | 1 - src/nvim/sign.c | 7 +++++-- src/nvim/spell.c | 1 - src/nvim/spellfile.c | 1 - src/nvim/spellsuggest.c | 1 - src/nvim/state.c | 4 +++- src/nvim/strings.c | 7 ++++--- src/nvim/strings.h | 6 ++++-- src/nvim/syntax.c | 1 - src/nvim/tag.c | 1 - src/nvim/terminal.c | 1 - src/nvim/testing.c | 1 - src/nvim/textformat.c | 1 - src/nvim/textobject.c | 1 - src/nvim/tui/input.c | 1 - src/nvim/tui/tui.c | 1 - src/nvim/ui_client.c | 1 - src/nvim/undo.c | 1 - src/nvim/usercmd.c | 1 - src/nvim/version.c | 1 - src/nvim/viml/parser/expressions.c | 1 - src/nvim/viml/parser/parser.c | 1 + src/nvim/window.c | 1 - src/nvim/winfloat.c | 1 - 135 files changed, 141 insertions(+), 185 deletions(-) (limited to 'src') diff --git a/src/klib/kvec.h b/src/klib/kvec.h index 5677a93b1b..f9ecca3d55 100644 --- a/src/klib/kvec.h +++ b/src/klib/kvec.h @@ -160,10 +160,12 @@ (v).size = 0, \ (v).items = (v).init_array) +static inline void *_memcpy_free(void *restrict dest, void *restrict src, size_t size) + REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET REAL_FATTR_ALWAYS_INLINE; + /// Move data to a new destination and free source static inline void *_memcpy_free(void *const restrict dest, void *const restrict src, const size_t size) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_ALWAYS_INLINE { memcpy(dest, src, size); XFREE_CLEAR(src); diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 3505f8be4f..a8ce9edff8 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -463,7 +463,7 @@ endif() #------------------------------------------------------------------------------- get_target_property(prop main_lib INTERFACE_COMPILE_DEFINITIONS) -foreach(gen_cdef DO_NOT_DEFINE_EMPTY_ATTRIBUTES ${prop}) +foreach(gen_cdef ${prop}) if(NOT ${gen_cdef} MATCHES "INCLUDE_GENERATED_DECLARATIONS") list(APPEND gen_cflags "-D${gen_cdef}") endif() diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 08d9d8e117..2ce08bdf40 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -17,7 +17,6 @@ #include "nvim/buffer.h" #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/lua/executor.h" #include "nvim/memory.h" diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 0df231868d..9d0ac5d6ef 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -24,7 +24,6 @@ #include "nvim/drawscreen.h" #include "nvim/ex_cmds.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/lua/executor.h" #include "nvim/mapping.h" diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 2a57ce9a19..7116f4bce0 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -18,7 +18,6 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/globals.h" #include "nvim/lua/executor.h" diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 2ec11236d7..11795033cc 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -14,7 +14,6 @@ #include "nvim/buffer_defs.h" #include "nvim/decoration.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/highlight.h" #include "nvim/highlight_group.h" diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index d71498d6ed..80b1546329 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -17,7 +17,6 @@ #include "nvim/decoration_provider.h" #include "nvim/drawscreen.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" #include "nvim/grid.h" #include "nvim/highlight_group.h" #include "nvim/marktree.h" diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index c012a69c7b..9cf91bad42 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -11,7 +11,6 @@ #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/eval/window.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c index 90023171e5..ef57bde32d 100644 --- a/src/nvim/api/private/converter.c +++ b/src/nvim/api/private/converter.c @@ -11,7 +11,6 @@ #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" #include "nvim/eval/userfunc.h" -#include "nvim/func_attr.h" #include "nvim/lua/executor.h" #include "nvim/memory.h" #include "nvim/types_defs.h" diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index be39836a5b..b23684aee9 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -20,7 +20,6 @@ #include "nvim/eval/typval_defs.h" #include "nvim/eval/vars.h" #include "nvim/ex_eval.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/globals.h" #include "nvim/highlight_group.h" diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index c854a22477..303f2ca817 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -6,11 +6,14 @@ #include "nvim/api/tabpage.h" #include "nvim/api/vim.h" #include "nvim/buffer_defs.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/memory.h" #include "nvim/window.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/tabpage.c.generated.h" +#endif + /// Gets the windows in a tabpage /// /// @param tabpage Tabpage handle, or 0 for current tabpage diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 836a68546c..7e64ce9cd1 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -17,7 +17,6 @@ #include "nvim/eval.h" #include "nvim/event/loop.h" #include "nvim/event/wstream.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight.h" diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index d631b10af9..270f2e4432 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -31,7 +31,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/grid.h" diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index c75bf21572..25a34f769c 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -15,7 +15,6 @@ #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/globals.h" #include "nvim/memory.h" diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 4e23717dc6..825a0583ef 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -13,7 +13,6 @@ #include "nvim/buffer_defs.h" #include "nvim/decoration.h" #include "nvim/drawscreen.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight_group.h" diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index de5b40940f..d18971c756 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -15,7 +15,6 @@ #include "nvim/drawscreen.h" #include "nvim/eval/window.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/lua/executor.h" @@ -27,6 +26,10 @@ #include "nvim/types_defs.h" #include "nvim/window.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/window.c.generated.h" +#endif + /// Gets the current buffer in a window /// /// @param window Window handle, or 0 for current window diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c index 84f4297c99..f575bf30b8 100644 --- a/src/nvim/arabic.c +++ b/src/nvim/arabic.c @@ -22,7 +22,6 @@ #include "nvim/arabic.h" #include "nvim/ascii_defs.h" -#include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/option_vars.h" diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index d2734e6c5a..541534abf9 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -20,7 +20,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/ascii_defs.h b/src/nvim/ascii_defs.h index 4125336796..3de04cd9fa 100644 --- a/src/nvim/ascii_defs.h +++ b/src/nvim/ascii_defs.h @@ -107,6 +107,10 @@ static inline bool ascii_isbdigit(int c) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; +static inline bool ascii_isodigit(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; + static inline bool ascii_isspace(int c) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 74a1dbdbc3..044746b7be 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -23,7 +23,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/base64.c b/src/nvim/base64.c index 295dedd8d3..7f7d121442 100644 --- a/src/nvim/base64.c +++ b/src/nvim/base64.c @@ -3,7 +3,7 @@ #include #include -#include "auto/config.h" // IWYU pragma: keep +#include "auto/config.h" #include "nvim/base64.h" #include "nvim/memory.h" @@ -12,7 +12,7 @@ #endif #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "base64.c.generated.h" // IWYU pragma: export +# include "base64.c.generated.h" #endif static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -65,6 +65,7 @@ static inline uint32_t htobe32(uint32_t host_32bits) /// @param src_len Length of the string /// @return Base64 encoded string char *base64_encode(const char *src, size_t src_len) + FUNC_ATTR_NONNULL_ALL { assert(src != NULL); diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index 01bcb9d7be..a91a890d0e 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -11,7 +11,6 @@ #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/lua/executor.h" @@ -22,7 +21,7 @@ #include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "buffer_updates.c.generated.h" // IWYU pragma: export +# include "buffer_updates.c.generated.h" #endif // Register a channel. Return True if the channel was added, or already added. diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index f774fcb057..06bd05b11d 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -23,7 +23,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_eval.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight.h" diff --git a/src/nvim/change.c b/src/nvim/change.c index 81a55b92ee..efc2db1413 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -21,7 +21,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/extmark.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight.h" diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 5c9d708ac2..6deea08c83 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -122,7 +122,9 @@ static inline Channel *find_channel(uint64_t id) } static inline Stream *channel_instream(Channel *chan) - FUNC_ATTR_NONNULL_ALL + REAL_FATTR_NONNULL_ALL; + +static inline Stream *channel_instream(Channel *chan) { switch (chan->streamtype) { case kChannelStreamProc: @@ -142,7 +144,9 @@ static inline Stream *channel_instream(Channel *chan) } static inline Stream *channel_outstream(Channel *chan) - FUNC_ATTR_NONNULL_ALL + REAL_FATTR_NONNULL_ALL; + +static inline Stream *channel_outstream(Channel *chan) { switch (chan->streamtype) { case kChannelStreamProc: diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 367b86ec55..523145af1b 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -26,7 +26,6 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/garray_defs.h" #include "nvim/getchar.h" diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index 4556b74396..7ebe3c34a1 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -15,7 +15,6 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_getln.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/context.c b/src/nvim/context.c index 59309fcf16..5f47cfc225 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -16,7 +16,6 @@ #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/hashtab.h" #include "nvim/keycodes.h" #include "nvim/memory.h" diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index 5aff3b5598..fe07c33df5 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -8,7 +8,6 @@ #include "nvim/charset.h" #include "nvim/cursor_shape.h" #include "nvim/ex_getln.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight_group.h" diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index a343c1ad6b..000fe13502 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -18,7 +18,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0b7f6f266b..6578a1121c 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -32,7 +32,6 @@ #include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 99d5cf1035..6b3c4e902b 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -17,7 +17,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 6cc623cb72..1abbc0c102 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -76,7 +76,6 @@ #include "nvim/eval.h" #include "nvim/ex_getln.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 71a12ea1b0..dd7cd9a573 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -24,7 +24,6 @@ #include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" @@ -1472,7 +1471,7 @@ void edit_putchar(int c, bool highlight) /// @return the effective prompt for the specified buffer. char *buf_prompt_text(const buf_T *const buf) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { if (buf->b_prompt_text == NULL) { return "% "; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f4479d06a6..a43ca3d78a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -36,7 +36,6 @@ #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/ex_session.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/eval/buffer.c b/src/nvim/eval/buffer.c index c60a104381..1f3b92804d 100644 --- a/src/nvim/eval/buffer.c +++ b/src/nvim/eval/buffer.c @@ -14,7 +14,6 @@ #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/memline.h" diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 03f79fca84..a6407693d7 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -14,7 +14,6 @@ #include "nvim/eval/encode.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h index 26a3286f2b..699956d8ac 100644 --- a/src/nvim/eval/encode.h +++ b/src/nvim/eval/encode.h @@ -36,9 +36,11 @@ typedef struct { size_t li_length; ///< Length of the string inside the read item. } ListReaderState; +static inline ListReaderState encode_init_lrstate(const list_T *list) + REAL_FATTR_NONNULL_ALL; + /// Initialize ListReaderState structure static inline ListReaderState encode_init_lrstate(const list_T *const list) - FUNC_ATTR_NONNULL_ALL { return (ListReaderState) { .list = list, diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index dc23fcdc72..b483f5fbef 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -5,7 +5,6 @@ #include "nvim/eval/executor.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" @@ -15,7 +14,7 @@ #include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "eval/executor.c.generated.h" // IWYU pragma: export +# include "eval/executor.c.generated.h" #endif char *e_list_index_out_of_range_nr diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 13425b21d1..0054c47678 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -58,7 +58,6 @@ #include "nvim/ex_getln.h" #include "nvim/file_search.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 58f74a9796..efa6017f4b 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -85,6 +85,9 @@ static inline void tv_list_set_lock(list_T *const l, const VarLockStatus lock) l->lv_lock = lock; } +static inline void tv_list_set_copyid(list_T *l, int copyid) + REAL_FATTR_NONNULL_ALL; + /// Set list copyID /// /// Does not expect NULL list, be careful. @@ -92,7 +95,6 @@ static inline void tv_list_set_lock(list_T *const l, const VarLockStatus lock) /// @param[out] l List to modify. /// @param[in] copyid New copyID. static inline void tv_list_set_copyid(list_T *const l, const int copyid) - FUNC_ATTR_NONNULL_ALL { l->lv_copyID = copyid; } @@ -442,22 +444,20 @@ static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret } static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q) - REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET REAL_FATTR_PURE - REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE - FUNC_ATTR_NO_SANITIZE_ADDRESS; + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET + REAL_FATTR_NO_SANITIZE_ADDRESS REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; /// Compute the `DictWatcher` address from a QUEUE node. /// /// This only exists for .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer /// arithmetic). static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q) - FUNC_ATTR_NO_SANITIZE_ADDRESS { return QUEUE_DATA(q, DictWatcher, node); } static inline bool tv_is_func(typval_T tv) - FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST; + REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST; /// Check whether given typval_T contains a function /// diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 23b3c4e1b2..e0bf30b158 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -23,7 +23,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 2968f75f4d..670ee39f4b 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -25,7 +25,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index be48b39af1..8264adb1fc 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -7,7 +7,6 @@ #include "nvim/event/libuv_process.h" #include "nvim/event/process.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/log.h" #include "nvim/os/os.h" #include "nvim/ui_client.h" diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 3ab41bd299..677b7e8e6a 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -48,7 +48,6 @@ #include "nvim/event/defs.h" #include "nvim/event/multiqueue.h" -#include "nvim/func_attr.h" #include "nvim/lib/queue.h" #include "nvim/memory.h" diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 864fc2c1d8..b69612337c 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -7,7 +7,6 @@ #include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" #include "nvim/event/process.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/main.h" diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 73828a2271..88363e86e9 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -8,7 +8,6 @@ #include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/log.h" #include "nvim/macros_defs.h" #include "nvim/main.h" diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index e64d526856..07223be987 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -3,7 +3,6 @@ #include "nvim/event/loop.h" #include "nvim/event/signal.h" -#include "nvim/func_attr.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/signal.c.generated.h" diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index e787e023f0..c90b177eb7 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -10,7 +10,6 @@ #include "nvim/event/loop.h" #include "nvim/event/socket.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/log.h" #include "nvim/main.h" diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index aff116bad9..17c1b0a072 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -6,7 +6,6 @@ #include "nvim/event/loop.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/log.h" #include "nvim/rbuffer.h" #ifdef MSWIN diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index f678f25f3f..0b624d9547 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -3,7 +3,6 @@ #include "nvim/event/loop.h" #include "nvim/event/time.h" -#include "nvim/func_attr.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/time.c.generated.h" diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index e8f757874b..239f64c013 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -5,7 +5,6 @@ #include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/event/wstream.h" -#include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index e369397047..c0aca071e2 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -43,7 +43,6 @@ #include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 245121f4af..bf5a3944e6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -39,7 +39,6 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index d2a1d53b78..bc4cb634e8 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -18,7 +18,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/ex_eval_defs.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/memory.h" diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 64ef17b157..f31f8fec55 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -34,7 +34,6 @@ #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 71c01922bc..45f05e10f2 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -20,7 +20,6 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 0bb664bcf5..4fe5b1cd44 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -31,7 +31,6 @@ #include "nvim/ex_eval.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/garray_defs.h" #include "nvim/getchar.h" diff --git a/src/nvim/fold.c b/src/nvim/fold.c index c905b2d3ed..e372b9f461 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -27,7 +27,6 @@ #include "nvim/ex_session.h" #include "nvim/extmark.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/garray_defs.h" #include "nvim/gettext.h" diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index 15370dcb3e..d638fda531 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -1,24 +1,16 @@ -// If DEFINE_FUNC_ATTRIBUTES macro is not defined then all function attributes -// are defined as empty values. -// -// If DO_NOT_DEFINE_EMPTY_ATTRIBUTES then empty macros are not defined. Thus -// undefined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES +// Undefined DEFINE_FUNC_ATTRIBUTES and undefined DEFINE_EMPTY_ATTRIBUTES // leaves file with untouched FUNC_ATTR_* macros. This variant is used for -// scripts/gendeclarations.lua. +// scripts/gen_declarations.lua. // -// Empty macros are used for *.c files. (undefined DEFINE_FUNC_ATTRIBUTES and -// undefined DO_NOT_DEFINE_EMPTY_ATTRIBUTES) +// Empty macros are used for *.c files. +// (undefined DEFINE_FUNC_ATTRIBUTES and defined DEFINE_EMPTY_ATTRIBUTES) // // Macros defined as __attribute__((*)) are used by generated header files. -// (defined DEFINE_FUNC_ATTRIBUTES and undefined -// DO_NOT_DEFINE_EMPTY_ATTRIBUTES) -// -// Defined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES is -// not used by anything. +// (defined DEFINE_FUNC_ATTRIBUTES and undefined DEFINE_EMPTY_ATTRIBUTES) // FUNC_ATTR_* macros should be in *.c files for declarations generator. If you // define a function for which declaration is not generated by -// gendeclarations.lua (e.g. template hash implementation) then you should use +// gen_declarations.lua (e.g. template hash implementation) then you should use // REAL_FATTR_* macros. // gcc and clang expose their version as follows: @@ -217,7 +209,7 @@ # endif #endif -#ifdef DEFINE_FUNC_ATTRIBUTES +#if defined(DEFINE_FUNC_ATTRIBUTES) || defined(DEFINE_EMPTY_ATTRIBUTES) /// Fast (non-deferred) API function. # define FUNC_API_FAST /// Internal C function not exposed in the RPC API. @@ -234,6 +226,9 @@ # define FUNC_API_SINCE(X) /// API function deprecated since the given API level. # define FUNC_API_DEPRECATED_SINCE(X) +#endif + +#if defined(DEFINE_FUNC_ATTRIBUTES) # define FUNC_ATTR_MALLOC REAL_FATTR_MALLOC # define FUNC_ATTR_ALLOC_SIZE(x) REAL_FATTR_ALLOC_SIZE(x) # define FUNC_ATTR_ALLOC_SIZE_PROD(x, y) REAL_FATTR_ALLOC_SIZE_PROD(x, y) @@ -250,7 +245,7 @@ # define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED # define FUNC_ATTR_NO_SANITIZE_ADDRESS REAL_FATTR_NO_SANITIZE_ADDRESS # define FUNC_ATTR_PRINTF(x, y) REAL_FATTR_PRINTF(x, y) -#elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES) +#elif defined(DEFINE_EMPTY_ATTRIBUTES) # define FUNC_ATTR_MALLOC # define FUNC_ATTR_ALLOC_SIZE(x) # define FUNC_ATTR_ALLOC_SIZE_PROD(x, y) diff --git a/src/nvim/garray.c b/src/nvim/garray.c index 24b6fb0007..28339c3059 100644 --- a/src/nvim/garray.c +++ b/src/nvim/garray.c @@ -5,7 +5,6 @@ #include #include -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/log.h" #include "nvim/memory.h" @@ -13,7 +12,7 @@ #include "nvim/strings.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "garray.c.generated.h" // IWYU pragma: export +# include "garray.c.generated.h" #endif /// Clear an allocated growing array. diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 9720cca477..81b5096557 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -752,9 +752,9 @@ for _, fn in ipairs(functions) do end output:write(string.format([[ -void nlua_add_api_functions(lua_State *lstate); // silence -Wmissing-prototypes void nlua_add_api_functions(lua_State *lstate) - FUNC_ATTR_NONNULL_ALL + REAL_FATTR_NONNULL_ALL; +void nlua_add_api_functions(lua_State *lstate) { lua_createtable(lstate, 0, %u); ]], #lua_c_functions)) diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua index f9e9c6b0a8..fecca5191e 100644 --- a/src/nvim/generators/gen_declarations.lua +++ b/src/nvim/generators/gen_declarations.lua @@ -164,7 +164,7 @@ if fname == '--help' then print([[ Usage: - gendeclarations.lua definitions.c static.h non-static.h definitions.i + gen_declarations.lua definitions.c static.h non-static.h definitions.i Generates declarations for a C file definitions.c, putting declarations for static functions into static.h and declarations for non-static functions into @@ -202,17 +202,10 @@ local text = preproc_f:read("*all") preproc_f:close() -local header = [[ +local non_static = [[ #define DEFINE_FUNC_ATTRIBUTES #include "nvim/func_attr.h" #undef DEFINE_FUNC_ATTRIBUTES -]] - -local footer = [[ -#include "nvim/func_attr.h" -]] - -local non_static = header .. [[ #ifndef DLLEXPORT # ifdef MSWIN # define DLLEXPORT __declspec(dllexport) @@ -222,7 +215,20 @@ local non_static = header .. [[ #endif ]] -local static = header +local static = [[ +#define DEFINE_FUNC_ATTRIBUTES +#include "nvim/func_attr.h" +#undef DEFINE_FUNC_ATTRIBUTES +]] + +local non_static_footer = [[ +#include "nvim/func_attr.h" +]] + +local static_footer = [[ +#define DEFINE_EMPTY_ATTRIBUTES +#include "nvim/func_attr.h" // IWYU pragma: export +]] if fname:find('.*/src/nvim/.*%.c$') then -- Add an IWYU pragma comment if the corresponding .h file exists. @@ -307,8 +313,8 @@ while init ~= nil do end end -non_static = non_static .. footer -static = static .. footer +non_static = non_static .. non_static_footer +static = static .. static_footer local F F = io.open(static_fname, 'w') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 73af78d3e2..0ccf1823f8 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -26,7 +26,6 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 475666be5e..e6a0e55ed2 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -24,7 +24,6 @@ #include #include "nvim/ascii_defs.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/hashtab.h" #include "nvim/memory.h" diff --git a/src/nvim/help.c b/src/nvim/help.c index c23dc7fd9d..dc4f6c44ff 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -16,7 +16,6 @@ #include "nvim/ex_docmd.h" #include "nvim/extmark_defs.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 3f1758894e..3953a459bc 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -24,7 +24,6 @@ #include "nvim/eval/typval_defs.h" #include "nvim/eval/vars.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 348f3a6528..5dced37b40 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -17,7 +17,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/indent.h" diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index c140d468d8..6c133c1e99 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -9,7 +9,6 @@ #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/edit.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/indent.h" #include "nvim/indent_c.h" diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 12543a2d42..8bf5e2c113 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -24,7 +24,6 @@ #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index 745500fe39..49ec245359 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -10,7 +10,6 @@ #include "nvim/charset.h" #include "nvim/eval/typval_defs.h" #include "nvim/eval/vars.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/keycodes.h" diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h index 40769e44b5..0c4ab7e9ed 100644 --- a/src/nvim/lib/queue.h +++ b/src/nvim/lib/queue.h @@ -44,22 +44,29 @@ typedef struct _queue { } // ffi.cdef is unable to swallow `bool` in place of `int` here. +static inline int QUEUE_EMPTY(const QUEUE *q) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; + static inline int QUEUE_EMPTY(const QUEUE *const q) - FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return q == q->next; } #define QUEUE_HEAD(q) (q)->next -static inline void QUEUE_INIT(QUEUE *const q) FUNC_ATTR_ALWAYS_INLINE +static inline void QUEUE_INIT(QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_INIT(QUEUE *const q) { q->next = q; q->prev = q; } +static inline void QUEUE_ADD(QUEUE *h, QUEUE *n) + REAL_FATTR_ALWAYS_INLINE; + static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n) - FUNC_ATTR_ALWAYS_INLINE { h->prev->next = n->next; n->next->prev = h->prev; @@ -67,8 +74,10 @@ static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n) h->prev->next = h; } +static inline void QUEUE_INSERT_HEAD(QUEUE *h, QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q) - FUNC_ATTR_ALWAYS_INLINE { q->next = h->next; q->prev = h; @@ -76,8 +85,10 @@ static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q) h->next = q; } +static inline void QUEUE_INSERT_TAIL(QUEUE *h, QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + static inline void QUEUE_INSERT_TAIL(QUEUE *const h, QUEUE *const q) - FUNC_ATTR_ALWAYS_INLINE { q->next = h; q->prev = h->prev; @@ -85,7 +96,10 @@ static inline void QUEUE_INSERT_TAIL(QUEUE *const h, QUEUE *const q) h->prev = q; } -static inline void QUEUE_REMOVE(QUEUE *const q) FUNC_ATTR_ALWAYS_INLINE +static inline void QUEUE_REMOVE(QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_REMOVE(QUEUE *const q) { q->prev->next = q->next; q->next->prev = q->prev; diff --git a/src/nvim/log.c b/src/nvim/log.c index aeee088cd3..a93dab6238 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -19,7 +19,6 @@ #include "auto/config.h" #include "nvim/ascii_defs.h" #include "nvim/eval.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/memory.h" diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 4598d48c4a..fd2bdbd677 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -16,7 +16,6 @@ #include "nvim/eval/typval_defs.h" #include "nvim/eval/typval_encode.h" #include "nvim/eval/userfunc.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/lua/converter.h" #include "nvim/lua/executor.h" diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 33770b2e62..d7a7abe3c8 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -22,7 +22,6 @@ #include "nvim/eval/vars.h" #include "nvim/ex_eval.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/lua/base64.h" #include "nvim/lua/converter.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index 6585bd1df7..544196d78a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -44,7 +44,6 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 17593a9121..56544a9956 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -24,7 +24,6 @@ #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_session.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" @@ -143,7 +142,7 @@ mapblock_T *get_buf_maphash_list(int state, int c) /// @param index The index in the maphash[] /// @param buf The buffer to get the maphash from. NULL for global mapblock_T *get_maphash(int index, buf_T *buf) - FUNC_ATTR_PURE + FUNC_ATTR_PURE { if (index >= MAX_MAPHASH) { return NULL; diff --git a/src/nvim/mark.h b/src/nvim/mark.h index 3237ae541e..c73c649789 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -50,9 +50,11 @@ SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ } while (0) +static inline int mark_global_index(char name) + REAL_FATTR_CONST; + /// Convert mark name to the offset static inline int mark_global_index(const char name) - FUNC_ATTR_CONST { return (ASCII_ISUPPER(name) ? (name - 'A') @@ -61,9 +63,11 @@ static inline int mark_global_index(const char name) : -1)); } +static inline int mark_local_index(char name) + REAL_FATTR_CONST; + /// Convert local mark name to the offset static inline int mark_local_index(const char name) - FUNC_ATTR_CONST { return (ASCII_ISLOWER(name) ? (name - 'a') diff --git a/src/nvim/match.c b/src/nvim/match.c index 0a7c264d4f..7543fb2b9d 100644 --- a/src/nvim/match.c +++ b/src/nvim/match.c @@ -16,7 +16,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight.h" diff --git a/src/nvim/math.c b/src/nvim/math.c index 96ff1bef10..79e0be691b 100644 --- a/src/nvim/math.c +++ b/src/nvim/math.c @@ -7,10 +7,11 @@ #include "nvim/math.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "math.c.generated.h" // IWYU pragma: export +# include "math.c.generated.h" #endif int xfpclassify(double d) + FUNC_ATTR_CONST { uint64_t m; @@ -29,11 +30,13 @@ int xfpclassify(double d) } int xisinf(double d) + FUNC_ATTR_CONST { return FP_INFINITE == xfpclassify(d); } int xisnan(double d) + FUNC_ATTR_CONST { return FP_NAN == xfpclassify(d); } diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 3c671121b7..5e768839ba 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -56,7 +56,6 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/memory.c b/src/nvim/memory.c index df6c81fe0d..35ae6afde7 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -16,7 +16,6 @@ #include "nvim/decoration_provider.h" #include "nvim/drawline.h" #include "nvim/eval.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight.h" diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 3252a73970..bc850d8961 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -15,7 +15,6 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/message.c b/src/nvim/message.c index 3268ff389a..8d11b793dc 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -24,7 +24,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_eval.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 8fe3864424..7a7b687385 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -15,7 +15,6 @@ #include "nvim/eval/typval.h" #include "nvim/ex_docmd.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/grid.h" diff --git a/src/nvim/move.c b/src/nvim/move.c index 9ed3978490..227d064a27 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -22,7 +22,6 @@ #include "nvim/eval/typval.h" #include "nvim/eval/window.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 0fb1ebf931..50210e4936 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -20,7 +20,6 @@ #include "nvim/event/rstream.h" #include "nvim/event/stream.h" #include "nvim/event/wstream.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/main.h" diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 1fdfc9e536..d2be321e7a 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -10,7 +10,6 @@ #include "msgpack/pack.h" #include "nvim/api/private/helpers.h" #include "nvim/assert_defs.h" -#include "nvim/func_attr.h" #include "nvim/memory.h" #include "nvim/msgpack_rpc/helpers.h" #include "nvim/types_defs.h" diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index f3627eaa61..e60c1b88a5 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -7,7 +7,6 @@ #include "nvim/channel.h" #include "nvim/eval.h" #include "nvim/event/socket.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/log.h" #include "nvim/main.h" diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 1f789dc153..8083bb00f5 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -34,7 +34,6 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 67a613cbca..4dab51b15d 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -102,13 +102,15 @@ typedef enum { YREG_PUT, } yreg_mode_t; +static inline int op_reg_index(int regname) + REAL_FATTR_CONST; + /// Convert register name into register index /// /// @param[in] regname Register name. /// /// @return Index in y_regs array or -1 if register name was not recognized. static inline int op_reg_index(const int regname) - FUNC_ATTR_CONST { if (ascii_isdigit(regname)) { return regname - '0'; @@ -127,11 +129,13 @@ static inline int op_reg_index(const int regname) } } +static inline bool is_literal_register(int regname) + REAL_FATTR_CONST; + /// @see get_yank_register /// @return true when register should be inserted literally /// (selection or clipboard) static inline bool is_literal_register(const int regname) - FUNC_ATTR_CONST { return regname == '*' || regname == '+'; } diff --git a/src/nvim/option.c b/src/nvim/option.c index 96d6d8e01e..882722a575 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -49,7 +49,6 @@ #include "nvim/ex_getln.h" #include "nvim/ex_session.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 281ec86171..0a7d77e817 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -19,7 +19,6 @@ #include "nvim/eval/vars.h" #include "nvim/ex_getln.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight_group.h" diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 8620c79069..b1e680e469 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -14,7 +14,6 @@ #include "nvim/charset.h" #include "nvim/cmdexpand.h" #include "nvim/eval.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/log.h" @@ -46,6 +45,10 @@ # include #endif +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/env.c.generated.h" +#endif + // Because `uv_os_getenv` requires allocating, we must manage a map to maintain // the behavior of `os_getenv`. static PMap(cstr_t) envmap = MAP_INIT; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 8f939c3b40..a8c7fcc38f 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -17,7 +17,6 @@ #endif #include "auto/config.h" -#include "nvim/func_attr.h" #include "nvim/os/fs.h" #if defined(HAVE_ACL) diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index f3bd1c7ed9..b86c51424c 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -12,7 +12,6 @@ #include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c index d9ec3a7a8a..5263451488 100644 --- a/src/nvim/os/process.c +++ b/src/nvim/os/process.c @@ -44,7 +44,7 @@ #endif #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/process.c.generated.h" // IWYU pragma: export +# include "os/process.c.generated.h" #endif #ifdef MSWIN @@ -114,6 +114,7 @@ bool os_proc_tree_kill(int pid, int sig) /// @param[out] proc_count Number of child processes. /// @return 0 on success, 1 if process not found, 2 on other error. int os_proc_children(int ppid, int **proc_list, size_t *proc_count) + FUNC_ATTR_NONNULL_ALL { if (ppid < 0) { return 2; diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index f801646967..d4be3086ea 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -35,7 +35,6 @@ #include "nvim/event/loop.h" #include "nvim/event/process.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/log.h" #include "nvim/os/fs.h" #include "nvim/os/os_defs.h" diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 191be784e8..cb8066a62d 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -20,7 +20,6 @@ #include "nvim/event/wstream.h" #include "nvim/ex_cmds.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index c920cb655e..3a861b87b4 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -9,7 +9,6 @@ #include "nvim/autocmd.h" #include "nvim/eval.h" #include "nvim/event/signal.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/main.h" diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 7691aa5122..ede17bc7c8 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -4,13 +4,16 @@ #include "nvim/ascii_defs.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/memory.h" #include "nvim/os/os.h" #include "nvim/os/stdpaths_defs.h" #include "nvim/path.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/stdpaths.c.generated.h" +#endif + /// Names of the environment variables, mapped to XDGVarType values static const char *xdg_env_vars[] = { [kXDGConfigHome] = "XDG_CONFIG_HOME", diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 49b43af6c0..7f3e44f680 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -8,7 +8,6 @@ #include "auto/config.h" #include "nvim/event/loop.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/log.h" @@ -19,7 +18,7 @@ #include "nvim/os/time.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/time.c.generated.h" // IWYU pragma: export +# include "os/time.c.generated.h" #endif /// Gets a high-resolution (nanosecond), monotonically-increasing time relative diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index ae0994a73f..5db7a19411 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -22,6 +22,10 @@ # include "nvim/message.h" #endif +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/users.c.generated.h" +#endif + // All user names (for ~user completion as done by shell). static garray_T ga_users = GA_EMPTY_INIT_VALUE; diff --git a/src/nvim/path.c b/src/nvim/path.c index c7212c7ade..100d66dfff 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -153,7 +153,7 @@ char *path_tail_with_sep(char *fname) /// /// @return The position of the last path separator + 1. const char *invocation_path_tail(const char *invocation, size_t *len) - FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) { const char *tail = get_past_head(invocation); const char *p = tail; diff --git a/src/nvim/plines.c b/src/nvim/plines.c index 6e9f92c193..fbddb1ab4a 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -10,7 +10,6 @@ #include "nvim/decoration.h" #include "nvim/diff.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/indent.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/profile.c b/src/nvim/profile.c index 53ff57dacb..543f91304a 100644 --- a/src/nvim/profile.c +++ b/src/nvim/profile.c @@ -15,7 +15,6 @@ #include "nvim/eval/userfunc.h" #include "nvim/ex_cmds_defs.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 4e20eb8925..112f9aa35a 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -29,7 +29,6 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c index f74f68adb6..aff06ee31b 100644 --- a/src/nvim/rbuffer.c +++ b/src/nvim/rbuffer.c @@ -3,13 +3,12 @@ #include #include -#include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" #include "nvim/rbuffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "rbuffer.c.generated.h" // IWYU pragma: export +# include "rbuffer.c.generated.h" #endif /// Creates a new `RBuffer` instance. @@ -214,7 +213,7 @@ size_t rbuffer_read(RBuffer *buf, char *dst, size_t dst_size) } char *rbuffer_get(RBuffer *buf, size_t index) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { assert(index < buf->size); char *rptr = buf->read_ptr + index; diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 3536196a3b..20c06340be 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -21,7 +21,6 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 38d3942126..087c26a46f 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -26,7 +26,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/search.c b/src/nvim/search.c index 642219c1e0..a23d27635f 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -24,7 +24,6 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/shada.c b/src/nvim/shada.c index be898142f0..d288c36f65 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -25,7 +25,6 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/sign.c b/src/nvim/sign.c index d05c708d2c..f901f371ce 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -26,7 +26,6 @@ #include "nvim/ex_docmd.h" #include "nvim/extmark.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/highlight.h" @@ -46,6 +45,10 @@ #include "nvim/vim_defs.h" #include "nvim/window.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "sign.c.generated.h" +#endif + static PMap(cstr_t) sign_map INIT( = MAP_INIT); static kvec_t(Integer) sign_ns INIT( = MAP_INIT); @@ -910,7 +913,7 @@ static dict_T *sign_get_placed_info_dict(MTKey mark) /// Returns information about signs placed in a buffer as list of dicts. list_T *get_buffer_signs(buf_T *buf) - FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { list_T *const l = tv_list_alloc(kListLenMayKnow); MarkTreeIter itr[1]; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 905f5c25b4..5065bee347 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -73,7 +73,6 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 2607fddc31..4aa0508329 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -241,7 +241,6 @@ #include "nvim/drawscreen.h" #include "nvim/ex_cmds_defs.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index d9dd28527e..bdac5aa587 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -17,7 +17,6 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/garray_defs.h" #include "nvim/getchar.h" diff --git a/src/nvim/state.c b/src/nvim/state.c index 900eac0826..199003b61c 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -26,10 +26,11 @@ #include "nvim/ui.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "state.c.generated.h" // IWYU pragma: export +# include "state.c.generated.h" #endif void state_enter(VimState *s) + FUNC_ATTR_NONNULL_ALL { while (true) { int check_result = s->check ? s->check(s) : 1; @@ -168,6 +169,7 @@ int get_real_state(void) /// The first character represents the major mode, the following ones the minor /// ones. void get_mode(char *buf) + FUNC_ATTR_NONNULL_ALL { int i = 0; diff --git a/src/nvim/strings.c b/src/nvim/strings.c index a439d11818..169909ea56 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -30,6 +30,10 @@ #include "nvim/types_defs.h" #include "nvim/vim_defs.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "strings.c.generated.h" +#endif + static const char e_cannot_mix_positional_and_non_positional_str[] = N_("E1500: Cannot mix positional and non-positional arguments: %s"); static const char e_fmt_arg_nr_unused_str[] @@ -461,9 +465,6 @@ char *vim_strchr(const char *const string, const int c) // Sort an array of strings. -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "strings.c.generated.h" -#endif static int sort_compare(const void *s1, const void *s2) FUNC_ATTR_NONNULL_ALL { diff --git a/src/nvim/strings.h b/src/nvim/strings.h index d717362f87..8478676f13 100644 --- a/src/nvim/strings.h +++ b/src/nvim/strings.h @@ -10,6 +10,10 @@ #include "nvim/os/os_defs.h" #include "nvim/types_defs.h" // IWYU pragma: keep +static inline char *strappend(char *dst, const char *src) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL + REAL_FATTR_NONNULL_RET REAL_FATTR_WARN_UNUSED_RESULT; + /// Append string to string and return pointer to the next byte /// /// Unlike strcat, this one does *not* add NUL byte and returns pointer to the @@ -20,8 +24,6 @@ /// /// @return pointer to the byte just past the appended byte. static inline char *strappend(char *const dst, const char *const src) - FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT - FUNC_ATTR_NONNULL_RET { const size_t src_len = strlen(src); return (char *)memmove(dst, src, src_len) + src_len; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 11282ea170..f6f0fca74a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -20,7 +20,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/tag.c b/src/nvim/tag.c index c6a1a13606..7fa02d2e0a 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -23,7 +23,6 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 1527738165..03a7744b18 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -59,7 +59,6 @@ #include "nvim/event/multiqueue.h" #include "nvim/event/time.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/highlight.h" diff --git a/src/nvim/testing.c b/src/nvim/testing.c index cada04d276..6515da7500 100644 --- a/src/nvim/testing.c +++ b/src/nvim/testing.c @@ -12,7 +12,6 @@ #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index b69d438a59..7219e04add 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -14,7 +14,6 @@ #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" #include "nvim/globals.h" #include "nvim/indent.h" diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c index d4310d47a4..6e61e9be61 100644 --- a/src/nvim/textobject.c +++ b/src/nvim/textobject.c @@ -11,7 +11,6 @@ #include "nvim/edit.h" #include "nvim/eval/funcs.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/indent.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index bdbb5e4872..639bfc0f79 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -7,7 +7,6 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/event/defs.h" -#include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/main.h" #include "nvim/map_defs.h" diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 197bbcabb5..78e6cdf32a 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -18,7 +18,6 @@ #include "nvim/event/loop.h" #include "nvim/event/signal.h" #include "nvim/event/stream.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight_defs.h" diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index 30f44d182d..a7a1c5912a 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -11,7 +11,6 @@ #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" #include "nvim/event/loop.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/highlight.h" #include "nvim/log.h" diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 93a973c33d..928dd2967c 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -99,7 +99,6 @@ #include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index 7c65af5138..9872468ba9 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -16,7 +16,6 @@ #include "nvim/cmdexpand_defs.h" #include "nvim/eval.h" #include "nvim/ex_docmd.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/version.c b/src/nvim/version.c index cb9088afae..fc93a01b32 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -20,7 +20,6 @@ #include "nvim/charset.h" #include "nvim/drawscreen.h" #include "nvim/ex_cmds_defs.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/grid.h" diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c index 8b637fbb9b..11f5276053 100644 --- a/src/nvim/viml/parser/expressions.c +++ b/src/nvim/viml/parser/expressions.c @@ -59,7 +59,6 @@ #include "nvim/assert_defs.h" #include "nvim/charset.h" #include "nvim/eval.h" -#include "nvim/func_attr.h" #include "nvim/gettext.h" #include "nvim/keycodes.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/viml/parser/parser.c b/src/nvim/viml/parser/parser.c index b854aedca6..d8679208c3 100644 --- a/src/nvim/viml/parser/parser.c +++ b/src/nvim/viml/parser/parser.c @@ -5,6 +5,7 @@ #endif void parser_simple_get_line(void *cookie, ParserLine *ret_pline) + FUNC_ATTR_NONNULL_ALL { ParserLine **plines_p = (ParserLine **)cookie; *ret_pline = **plines_p; diff --git a/src/nvim/window.c b/src/nvim/window.c index bcf245ef93..7728efde33 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -33,7 +33,6 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 44f0e2fc0b..0eea21eb9d 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -9,7 +9,6 @@ #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" #include "nvim/drawscreen.h" -#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/macros_defs.h" -- cgit From ce56e0a845d68862118f44cb66c5f080e3c1bbed Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 17:16:57 +0800 Subject: refactor(IWYU): move UI and LineFlags to ui_defs.h (#26318) --- src/clint.py | 12 ++--- src/nvim/api/private/dispatch.h | 12 ++--- src/nvim/api/ui.h | 3 +- src/nvim/decoration.h | 10 ++-- src/nvim/decoration_defs.h | 2 + src/nvim/highlight.h | 2 +- src/nvim/lua/spell.c | 4 +- src/nvim/tui/tui.c | 2 +- src/nvim/tui/tui.h | 2 +- src/nvim/ui.c | 10 ++-- src/nvim/ui.h | 109 +++------------------------------------- src/nvim/ui_compositor.h | 3 +- src/nvim/ui_defs.h | 95 ++++++++++++++++++++++++++++++++++ 13 files changed, 134 insertions(+), 132 deletions(-) create mode 100644 src/nvim/ui_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 1f588322f3..cb43ed59c7 100755 --- a/src/clint.py +++ b/src/clint.py @@ -898,14 +898,10 @@ def CheckIncludes(filename, lines, error): # the Makefile. check_includes_ignore = [ "src/nvim/api/extmark.h", - "src/nvim/api/private/dispatch.h", "src/nvim/api/private/helpers.h", "src/nvim/api/private/validate.h", - "src/nvim/api/ui.h", - "src/nvim/ascii_defs.h", "src/nvim/assert_defs.h", "src/nvim/autocmd.h", - "src/nvim/autocmd_defs.h", "src/nvim/buffer.h", "src/nvim/buffer_defs.h", "src/nvim/channel.h", @@ -933,7 +929,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/event/time.h", "src/nvim/event/wstream.h", "src/nvim/ex_cmds.h", - "src/nvim/ex_cmds_defs.h", "src/nvim/ex_docmd.h", "src/nvim/extmark.h", "src/nvim/file_search.h", @@ -972,10 +967,7 @@ def CheckIncludes(filename, lines, error): "src/nvim/syntax.h", "src/nvim/textobject.h", "src/nvim/tui/input.h", - "src/nvim/tui/tui.h", "src/nvim/ui.h", - "src/nvim/ui_client.h", - "src/nvim/ui_compositor.h", "src/nvim/viml/parser/expressions.h", "src/nvim/viml/parser/parser.h", "src/nvim/window.h", @@ -999,8 +991,10 @@ def CheckIncludes(filename, lines, error): if name in skip_headers: continue if (not name.endswith('.h.generated.h') and + not name.endswith('/defs.h') and not name.endswith('_defs.h') and - not name.endswith('/defs.h')): + not name.endswith('_defs.generated.h') and + not name.endswith('_enum.generated.h')): error(filename, i, 'build/include_defs', 5, 'Headers should not include non-"_defs" headers') diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index 6a2c9eaf54..88f846f813 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -14,12 +14,12 @@ typedef Object (*ApiDispatchWrapper)(uint64_t channel_id, Array args, Arena *are struct MsgpackRpcRequestHandler { const char *name; ApiDispatchWrapper fn; - bool fast; // Function is safe to be executed immediately while running the - // uv loop (the loop is run very frequently due to breakcheck). - // If "fast" is false, the function is deferred, i e the call will - // be put in the event queue, for safe handling later. - bool arena_return; // return value is allocated in the arena (or statically) - // and should not be freed as such. + bool fast; ///< Function is safe to be executed immediately while running the + ///< uv loop (the loop is run very frequently due to breakcheck). + ///< If "fast" is false, the function is deferred, i e the call will + ///< be put in the event queue, for safe handling later. + bool arena_return; ///< return value is allocated in the arena (or statically) + ///< and should not be freed as such. }; extern const MsgpackRpcRequestHandler method_handlers[]; diff --git a/src/nvim/api/ui.h b/src/nvim/api/ui.h index 26a91d0dbc..b1f4ff97d9 100644 --- a/src/nvim/api/ui.h +++ b/src/nvim/api/ui.h @@ -4,9 +4,8 @@ #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" // IWYU pragma: keep -#include "nvim/map_defs.h" #include "nvim/types_defs.h" // IWYU pragma: keep -#include "nvim/ui.h" +#include "nvim/ui_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/ui.h.generated.h" diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index f5448c051b..e5bac169dc 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -14,9 +14,11 @@ // actual Decor* data is in decoration_defs.h -EXTERN const char *const virt_text_pos_str[] INIT( = { "eol", "overlay", "win_col", "right_align", - "inline" }); +/// Keep in sync with VirtTextPos in decoration_defs.h +EXTERN const char *const virt_text_pos_str[] +INIT( = { "eol", "overlay", "win_col", "right_align", "inline" }); +/// Keep in sync with HlMode in decoration_defs.h EXTERN const char *const hl_mode_str[] INIT( = { "", "replace", "combine", "blend" }); typedef enum { @@ -43,8 +45,8 @@ typedef struct { VirtTextPos pos; } ui; } data; - int attr_id; // cached lookup of inl.hl_id if it was a highlight - bool owned; // ephemeral decoration, free memory immediately + int attr_id; ///< cached lookup of inl.hl_id if it was a highlight + bool owned; ///< ephemeral decoration, free memory immediately DecorPriority priority; DecorRangeKind kind; /// Screen column to draw the virtual text. diff --git a/src/nvim/decoration_defs.h b/src/nvim/decoration_defs.h index dc5d7b9ae4..6e7dc08f80 100644 --- a/src/nvim/decoration_defs.h +++ b/src/nvim/decoration_defs.h @@ -15,6 +15,7 @@ typedef struct { typedef kvec_t(VirtTextChunk) VirtText; #define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE) +/// Keep in sync with virt_text_pos_str[] in decoration.h typedef enum { kVPosEndOfLine, kVPosOverlay, @@ -28,6 +29,7 @@ typedef kvec_t(struct virt_line { VirtText line; bool left_col; }) VirtLines; typedef uint16_t DecorPriority; #define DECOR_PRIORITY_BASE 0x1000 +/// Keep in sync with hl_mode_str[] in decoration.h typedef enum { kHlModeUnknown, kHlModeReplace, diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h index e5d3f3d1ca..346c8aa864 100644 --- a/src/nvim/highlight.h +++ b/src/nvim/highlight.h @@ -7,7 +7,7 @@ #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" // IWYU pragma: export #include "nvim/option_vars.h" -#include "nvim/ui.h" +#include "nvim/ui_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "highlight.h.generated.h" diff --git a/src/nvim/lua/spell.c b/src/nvim/lua/spell.c index c261c5105e..e6c38ea9cb 100644 --- a/src/nvim/lua/spell.c +++ b/src/nvim/lua/spell.c @@ -15,10 +15,11 @@ #include "nvim/spell.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "lua/spell.c.generated.h" // IWYU pragma: export +# include "lua/spell.c.generated.h" #endif int nlua_spell_check(lua_State *lstate) + FUNC_ATTR_NONNULL_ALL { if (lua_gettop(lstate) < 1) { return luaL_error(lstate, "Expected 1 argument"); @@ -99,6 +100,7 @@ static const luaL_Reg spell_functions[] = { }; int luaopen_spell(lua_State *L) + FUNC_ATTR_NONNULL_ALL { lua_newtable(L); luaL_register(L, NULL, spell_functions); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 78e6cdf32a..c71eb633e9 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -34,8 +34,8 @@ #include "nvim/tui/tui.h" #include "nvim/types_defs.h" #include "nvim/ugrid.h" -#include "nvim/ui.h" #include "nvim/ui_client.h" +#include "nvim/ui_defs.h" #ifdef MSWIN # include "nvim/os/os_win_console.h" diff --git a/src/nvim/tui/tui.h b/src/nvim/tui/tui.h index 8eb4ac9bd8..34a98004f3 100644 --- a/src/nvim/tui/tui.h +++ b/src/nvim/tui/tui.h @@ -3,7 +3,7 @@ #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -#include "nvim/ui.h" +#include "nvim/ui_defs.h" // IWYU pragma: keep typedef struct TUIData TUIData; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 36f34bc75a..07166d229e 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,11 @@ #include "nvim/window.h" #include "nvim/winfloat.h" +typedef struct ui_event_callback { + LuaRef cb; + bool ext_widgets[kUIGlobalCount]; +} UIEventCallback; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui.c.generated.h" #endif @@ -692,7 +696,7 @@ void ui_call_event(char *name, Array args) ui_log(name); } -void ui_cb_update_ext(void) +static void ui_cb_update_ext(void) { memset(ui_cb_ext, 0, ARRAY_SIZE(ui_cb_ext)); @@ -708,7 +712,7 @@ void ui_cb_update_ext(void) } } -void free_ui_event_callback(UIEventCallback *event_cb) +static void free_ui_event_callback(UIEventCallback *event_cb) { api_free_luaref(event_cb->cb); xfree(event_cb); diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 666a869c89..f61398a7a0 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -1,34 +1,16 @@ #pragma once -#include -#include -#include +#include // IWYU pragma: keep -#include "nvim/api/private/defs.h" +#include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/event/multiqueue.h" -#include "nvim/globals.h" -#include "nvim/highlight_defs.h" +#include "nvim/grid_defs.h" // IWYU pragma: keep +#include "nvim/highlight_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" -#include "nvim/memory.h" -#include "nvim/types_defs.h" - -struct ui_t; - -typedef enum { - kUICmdline = 0, - kUIPopupmenu, - kUITabline, - kUIWildmenu, - kUIMessages, -#define kUIGlobalCount kUILinegrid - kUILinegrid, - kUIMultigrid, - kUIHlState, - kUITermColors, - kUIFloatDebug, - kUIExtCount, -} UIExtension; +#include "nvim/types_defs.h" // IWYU pragma: keep +#include "nvim/ui_defs.h" // IWYU pragma: export +/// Keep in sync with UIExtension in ui_defs.h EXTERN const char *ui_ext_names[] INIT( = { "ext_cmdline", "ext_popupmenu", @@ -42,83 +24,6 @@ EXTERN const char *ui_ext_names[] INIT( = { "_debug_float", }); -typedef struct ui_t UI; - -enum { - kLineFlagWrap = 1, - kLineFlagInvalid = 2, -}; - -typedef int LineFlags; - -typedef struct { - uint64_t channel_id; - -#define UI_BUF_SIZE 4096 ///< total buffer size for pending msgpack data. - /// guaranteed size available for each new event (so packing of simple events - /// and the header of grid_line will never fail) -#define EVENT_BUF_SIZE 256 - char buf[UI_BUF_SIZE]; ///< buffer of packed but not yet sent msgpack data - char *buf_wptr; ///< write head of buffer - const char *cur_event; ///< name of current event (might get multiple arglists) - Array call_buf; ///< buffer for constructing a single arg list (max 16 elements!) - - // state for write_cb, while packing a single arglist to msgpack. This - // might fail due to buffer overflow. - size_t pack_totlen; - bool buf_overflow; - char *temp_buf; - - // We start packing the two outermost msgpack arrays before knowing the total - // number of elements. Thus track the location where array size will need - // to be written in the msgpack buffer, once the specific array is finished. - char *nevents_pos; - char *ncalls_pos; - uint32_t nevents; ///< number of distinct events (top-level args to "redraw" - uint32_t ncalls; ///< number of calls made to the current event (plus one for the name!) - bool flushed_events; ///< events where sent to client without "flush" event - - size_t ncells_pending; ///< total number of cells since last buffer flush - - int hl_id; // Current highlight for legacy put event. - Integer cursor_row, cursor_col; // Intended visible cursor position. - - // Position of legacy cursor, used both for drawing and visible user cursor. - Integer client_row, client_col; - bool wildmenu_active; -} UIData; - -struct ui_t { - bool rgb; - bool override; ///< Force highest-requested UI capabilities. - bool composed; - bool ui_ext[kUIExtCount]; ///< Externalized UI capabilities. - int width; - int height; - int pum_nlines; /// actual nr. lines shown in PUM - bool pum_pos; /// UI reports back pum position? - double pum_row; - double pum_col; - double pum_height; - double pum_width; - - // TUI fields. - char *term_name; - char *term_background; ///< Deprecated. No longer needed since background color detection happens - ///< in Lua. To be removed in a future release. - int term_colors; - bool stdin_tty; - bool stdout_tty; - - // TODO(bfredl): integrate into struct! - UIData data[1]; -}; - -typedef struct ui_event_callback { - LuaRef cb; - bool ext_widgets[kUIGlobalCount]; -} UIEventCallback; - // uncrustify:off #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui.h.generated.h" diff --git a/src/nvim/ui_compositor.h b/src/nvim/ui_compositor.h index f3f5981680..b0dd8e126b 100644 --- a/src/nvim/ui_compositor.h +++ b/src/nvim/ui_compositor.h @@ -1,10 +1,9 @@ #pragma once #include "nvim/api/private/defs.h" // IWYU pragma: keep -#include "nvim/event/defs.h" #include "nvim/grid_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -#include "nvim/ui.h" +#include "nvim/ui_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_compositor.h.generated.h" diff --git a/src/nvim/ui_defs.h b/src/nvim/ui_defs.h new file mode 100644 index 0000000000..c4707d4d7c --- /dev/null +++ b/src/nvim/ui_defs.h @@ -0,0 +1,95 @@ +#pragma once + +#include +#include +#include + +#include "nvim/api/private/defs.h" + +/// Keep in sync with ui_ext_names[] in ui.h +typedef enum { + kUICmdline = 0, + kUIPopupmenu, + kUITabline, + kUIWildmenu, + kUIMessages, +#define kUIGlobalCount kUILinegrid + kUILinegrid, + kUIMultigrid, + kUIHlState, + kUITermColors, + kUIFloatDebug, + kUIExtCount, +} UIExtension; + +enum { + kLineFlagWrap = 1, + kLineFlagInvalid = 2, +}; + +typedef int LineFlags; + +typedef struct ui_t UI; + +typedef struct { + uint64_t channel_id; + +#define UI_BUF_SIZE 4096 ///< total buffer size for pending msgpack data. + /// guaranteed size available for each new event (so packing of simple events + /// and the header of grid_line will never fail) +#define EVENT_BUF_SIZE 256 + char buf[UI_BUF_SIZE]; ///< buffer of packed but not yet sent msgpack data + char *buf_wptr; ///< write head of buffer + const char *cur_event; ///< name of current event (might get multiple arglists) + Array call_buf; ///< buffer for constructing a single arg list (max 16 elements!) + + // state for write_cb, while packing a single arglist to msgpack. This + // might fail due to buffer overflow. + size_t pack_totlen; + bool buf_overflow; + char *temp_buf; + + // We start packing the two outermost msgpack arrays before knowing the total + // number of elements. Thus track the location where array size will need + // to be written in the msgpack buffer, once the specific array is finished. + char *nevents_pos; + char *ncalls_pos; + uint32_t nevents; ///< number of distinct events (top-level args to "redraw" + uint32_t ncalls; ///< number of calls made to the current event (plus one for the name!) + bool flushed_events; ///< events where sent to client without "flush" event + + size_t ncells_pending; ///< total number of cells since last buffer flush + + int hl_id; // Current highlight for legacy put event. + Integer cursor_row, cursor_col; // Intended visible cursor position. + + // Position of legacy cursor, used both for drawing and visible user cursor. + Integer client_row, client_col; + bool wildmenu_active; +} UIData; + +struct ui_t { + bool rgb; + bool override; ///< Force highest-requested UI capabilities. + bool composed; + bool ui_ext[kUIExtCount]; ///< Externalized UI capabilities. + int width; + int height; + int pum_nlines; /// actual nr. lines shown in PUM + bool pum_pos; /// UI reports back pum position? + double pum_row; + double pum_col; + double pum_height; + double pum_width; + + // TUI fields. + char *term_name; + char *term_background; ///< Deprecated. No longer needed since background color detection happens + ///< in Lua. To be removed in a future release. + int term_colors; + bool stdin_tty; + bool stdout_tty; + + // TODO(bfredl): integrate into struct! + UIData data[1]; +}; -- cgit From 95dbf1af73a6f73f08f988adb6d6436d680f53c4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 18:41:52 +0800 Subject: refactor: move extern variables out of _defs.h files (#26320) --- src/clint.py | 26 +++++- src/nvim/buffer_defs.h | 12 +-- src/nvim/extmark.h | 2 +- src/nvim/highlight.h | 96 ++++++++++++++++++- src/nvim/highlight_defs.h | 232 +++++++++++++++------------------------------- src/nvim/main.c | 3 +- src/nvim/mark.h | 3 + src/nvim/mark_defs.h | 3 - src/nvim/winfloat.h | 11 +++ 9 files changed, 205 insertions(+), 183 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index cb43ed59c7..a45969af31 100755 --- a/src/clint.py +++ b/src/clint.py @@ -880,18 +880,21 @@ def CheckForHeaderGuard(filename, lines, error): error(filename, 0, 'build/header_guard', 5, 'No "#pragma once" found in header') + def CheckIncludes(filename, lines, error): - """Checks that headers only include _defs headers + """Checks that headers only include _defs headers. Args: filename: The name of the C++ header file. lines: An array of strings, each representing a line of the file. error: The function to call with any errors found. """ - if filename.endswith('.c.h') or filename.endswith('.in.h') or FileInfo(filename).RelativePath() in { + if (filename.endswith('.c.h') + or filename.endswith('.in.h') + or FileInfo(filename).RelativePath() in { 'func_attr.h', 'os/pty_process.h', - }: + }): return # These should be synced with the ignored headers in the `iwyu` target in @@ -999,6 +1002,21 @@ def CheckIncludes(filename, lines, error): 'Headers should not include non-"_defs" headers') +def CheckNonSymbols(filename, lines, error): + """Checks that a _defs.h header only contains non-symbols. + + Args: + filename: The name of the C++ header file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + for i, line in enumerate(lines): + # Only a check against extern variables for now. + if line.startswith('EXTERN ') or line.startswith('extern '): + error(filename, i, 'build/defs_header', 5, + '"_defs" headers should not contain extern variables') + + def CheckForBadCharacters(filename, lines, error): """Logs an error for each line containing bad characters. @@ -2286,6 +2304,8 @@ def ProcessFileData(filename, file_extension, lines, error, if file_extension == 'h': CheckForHeaderGuard(filename, lines, error) CheckIncludes(filename, lines, error) + if filename.endswith('/defs.h') or filename.endswith('_defs.h'): + CheckNonSymbols(filename, lines, error) RemoveMultiLineComments(filename, lines, error) clean_lines = CleansedLines(lines, init_lines) diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index e59539f900..8928eea028 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -357,8 +357,6 @@ typedef struct { #define BUF_UPDATE_CALLBACKS_INIT { LUA_NOREF, LUA_NOREF, LUA_NOREF, \ LUA_NOREF, LUA_NOREF, false, false } -EXTERN int curbuf_splice_pending INIT( = 0); - #define BUF_HAS_QF_ENTRY 1 #define BUF_HAS_LL_ENTRY 2 @@ -904,12 +902,7 @@ enum { kFloatAnchorSouth = 2, }; -// NW -> 0 -// NE -> kFloatAnchorEast -// SW -> kFloatAnchorSouth -// SE -> kFloatAnchorSouth | kFloatAnchorEast -EXTERN const char *const float_anchor_str[] INIT( = { "NW", "NE", "SW", "SE" }); - +/// Keep in sync with float_relative_str in winfloat.h typedef enum { kFloatRelativeEditor = 0, kFloatRelativeWindow = 1, @@ -917,9 +910,6 @@ typedef enum { kFloatRelativeMouse = 3, } FloatRelative; -EXTERN const char *const float_relative_str[] INIT( = { "editor", "win", - "cursor", "mouse" }); - typedef enum { kWinStyleUnused = 0, kWinStyleMinimal, /// Minimal UI: no number column, eob markers, etc diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index 061cd0ed5f..1a7a1ddeff 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -13,7 +13,7 @@ #include "nvim/pos_defs.h" #include "nvim/types_defs.h" -EXTERN int extmark_splice_pending INIT( = 0); +EXTERN int curbuf_splice_pending INIT( = 0); typedef kvec_t(MTPair) ExtmarkInfoArray; diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h index 346c8aa864..ea8a663a9f 100644 --- a/src/nvim/highlight.h +++ b/src/nvim/highlight.h @@ -6,9 +6,100 @@ #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" // IWYU pragma: export +#include "nvim/macros_defs.h" #include "nvim/option_vars.h" +#include "nvim/types_defs.h" #include "nvim/ui_defs.h" // IWYU pragma: keep +EXTERN const char *hlf_names[] INIT( = { + [HLF_8] = "SpecialKey", + [HLF_EOB] = "EndOfBuffer", + [HLF_TERM] = "TermCursor", + [HLF_TERMNC] = "TermCursorNC", + [HLF_AT] = "NonText", + [HLF_D] = "Directory", + [HLF_E] = "ErrorMsg", + [HLF_I] = "IncSearch", + [HLF_L] = "Search", + [HLF_LC] = "CurSearch", + [HLF_M] = "MoreMsg", + [HLF_CM] = "ModeMsg", + [HLF_N] = "LineNr", + [HLF_LNA] = "LineNrAbove", + [HLF_LNB] = "LineNrBelow", + [HLF_CLN] = "CursorLineNr", + [HLF_CLS] = "CursorLineSign", + [HLF_CLF] = "CursorLineFold", + [HLF_R] = "Question", + [HLF_S] = "StatusLine", + [HLF_SNC] = "StatusLineNC", + [HLF_C] = "WinSeparator", + [HLF_T] = "Title", + [HLF_V] = "Visual", + [HLF_VNC] = "VisualNC", + [HLF_VSP] = "VertSplit", + [HLF_W] = "WarningMsg", + [HLF_WM] = "WildMenu", + [HLF_FL] = "Folded", + [HLF_FC] = "FoldColumn", + [HLF_ADD] = "DiffAdd", + [HLF_CHD] = "DiffChange", + [HLF_DED] = "DiffDelete", + [HLF_TXD] = "DiffText", + [HLF_SC] = "SignColumn", + [HLF_CONCEAL] = "Conceal", + [HLF_SPB] = "SpellBad", + [HLF_SPC] = "SpellCap", + [HLF_SPR] = "SpellRare", + [HLF_SPL] = "SpellLocal", + [HLF_PNI] = "Pmenu", + [HLF_PSI] = "PmenuSel", + [HLF_PNK] = "PmenuKind", + [HLF_PSK] = "PmenuKindSel", + [HLF_PNX] = "PmenuExtra", + [HLF_PSX] = "PmenuExtraSel", + [HLF_PSB] = "PmenuSbar", + [HLF_PST] = "PmenuThumb", + [HLF_TP] = "TabLine", + [HLF_TPS] = "TabLineSel", + [HLF_TPF] = "TabLineFill", + [HLF_CUC] = "CursorColumn", + [HLF_CUL] = "CursorLine", + [HLF_MC] = "ColorColumn", + [HLF_QFL] = "QuickFixLine", + [HLF_0] = "Whitespace", + [HLF_INACTIVE] = "NormalNC", + [HLF_MSGSEP] = "MsgSeparator", + [HLF_NFLOAT] = "NormalFloat", + [HLF_MSG] = "MsgArea", + [HLF_BORDER] = "FloatBorder", + [HLF_WBR] = "WinBar", + [HLF_WBRNC] = "WinBarNC", + [HLF_CU] = "Cursor", + [HLF_BTITLE] = "FloatTitle", + [HLF_BFOOTER] = "FloatFooter", +}); + +EXTERN int highlight_attr[HLF_COUNT + 1]; // Highl. attr for each context. +EXTERN int highlight_attr_last[HLF_COUNT]; // copy for detecting changed groups +EXTERN int highlight_user[9]; // User[1-9] attributes +EXTERN int highlight_stlnc[9]; // On top of user +EXTERN int cterm_normal_fg_color INIT( = 0); +EXTERN int cterm_normal_bg_color INIT( = 0); +EXTERN RgbValue normal_fg INIT( = -1); +EXTERN RgbValue normal_bg INIT( = -1); +EXTERN RgbValue normal_sp INIT( = -1); + +EXTERN NS ns_hl_global INIT( = 0); // global highlight namespace +EXTERN NS ns_hl_win INIT( = -1); // highlight namespace for the current window +EXTERN NS ns_hl_fast INIT( = -1); // highlight namespace specified in a fast callback +EXTERN NS ns_hl_active INIT( = 0); // currently active/cached namespace + +EXTERN int *hl_attr_active INIT( = highlight_attr); + +// Enums need a typecast to be used as array index. +#define HL_ATTR(n) hl_attr_active[(int)(n)] + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "highlight.h.generated.h" #endif @@ -20,8 +111,6 @@ static inline int win_hl_attr(win_T *wp, int hlf) return ((wp->w_ns_hl_attr && ns_hl_fast < 0) ? wp->w_ns_hl_attr : hl_attr_active)[hlf]; } -#define HLATTRS_DICT_SIZE 16 - #define HL_SET_DEFAULT_COLORS(rgb_fg, rgb_bg, rgb_sp) \ do { \ bool dark_ = (*p_bg == 'd'); \ @@ -29,6 +118,3 @@ static inline int win_hl_attr(win_T *wp, int hlf) rgb_bg = rgb_bg != -1 ? rgb_bg : (dark_ ? 0x000000 : 0xFFFFFF); \ rgb_sp = rgb_sp != -1 ? rgb_sp : 0xFF0000; \ } while (0); - -// Enums need a typecast to be used as array index. -#define HL_ATTR(n) hl_attr_active[(int)(n)] diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index 24070199ee..ec77bf7860 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -1,9 +1,7 @@ #pragma once -#include - -#include "nvim/macros_defs.h" -#include "nvim/types_defs.h" +#include +#include typedef int32_t RgbValue; @@ -54,164 +52,78 @@ typedef struct attr_entry { } /// Values for index in highlight_attr[]. -/// When making changes, also update hlf_names below! +/// When making changes, also update hlf_names in highlight.h! typedef enum { - HLF_8 = 0, // Meta & special keys listed with ":map", text that is - // displayed different from what it is - HLF_EOB, // after the last line in the buffer - HLF_TERM, // terminal cursor focused - HLF_TERMNC, // terminal cursor unfocused - HLF_AT, // @ characters at end of screen, characters that don't really exist in the text - HLF_D, // directories in CTRL-D listing - HLF_E, // error messages - HLF_I, // incremental search - HLF_L, // last search string - HLF_LC, // current search match - HLF_M, // "--More--" message - HLF_CM, // Mode (e.g., "-- INSERT --") - HLF_N, // line number for ":number" and ":#" commands - HLF_LNA, // LineNrAbove - HLF_LNB, // LineNrBelow - HLF_CLN, // current line number when 'cursorline' is set - HLF_CLS, // current line sign column - HLF_CLF, // current line fold - HLF_R, // return to continue message and yes/no questions - HLF_S, // status lines - HLF_SNC, // status lines of not-current windows - HLF_C, // window split separators - HLF_VSP, // VertSplit - HLF_T, // Titles for output from ":set all", ":autocmd" etc. - HLF_V, // Visual mode - HLF_VNC, // Visual mode, autoselecting and not clipboard owner - HLF_W, // warning messages - HLF_WM, // Wildmenu highlight - HLF_FL, // Folded line - HLF_FC, // Fold column - HLF_ADD, // Added diff line - HLF_CHD, // Changed diff line - HLF_DED, // Deleted diff line - HLF_TXD, // Text Changed in diff line - HLF_SC, // Sign column - HLF_CONCEAL, // Concealed text - HLF_SPB, // SpellBad - HLF_SPC, // SpellCap - HLF_SPR, // SpellRare - HLF_SPL, // SpellLocal - HLF_PNI, // popup menu normal item - HLF_PSI, // popup menu selected item - HLF_PNK, // popup menu normal item "kind" - HLF_PSK, // popup menu selected item "kind" - HLF_PNX, // popup menu normal item "menu" (extra text) - HLF_PSX, // popup menu selected item "menu" (extra text) - HLF_PSB, // popup menu scrollbar - HLF_PST, // popup menu scrollbar thumb - HLF_TP, // tabpage line - HLF_TPS, // tabpage line selected - HLF_TPF, // tabpage line filler - HLF_CUC, // 'cursorcolumn' - HLF_CUL, // 'cursorline' - HLF_MC, // 'colorcolumn' - HLF_QFL, // selected quickfix line - HLF_0, // Whitespace - HLF_INACTIVE, // NormalNC: Normal text in non-current windows - HLF_MSGSEP, // message separator line - HLF_NFLOAT, // Floating window - HLF_MSG, // Message area - HLF_BORDER, // Floating window border - HLF_WBR, // Window bars - HLF_WBRNC, // Window bars of not-current windows - HLF_CU, // Cursor - HLF_BTITLE, // Float Border Title - HLF_BFOOTER, // Float Border Footer - HLF_COUNT, // MUST be the last one + HLF_8 = 0, ///< Meta & special keys listed with ":map", text that is + ///< displayed different from what it is + HLF_EOB, ///< after the last line in the buffer + HLF_TERM, ///< terminal cursor focused + HLF_TERMNC, ///< terminal cursor unfocused + HLF_AT, ///< @ characters at end of screen, characters that don't really exist in the text + HLF_D, ///< directories in CTRL-D listing + HLF_E, ///< error messages + HLF_I, ///< incremental search + HLF_L, ///< last search string + HLF_LC, ///< current search match + HLF_M, ///< "--More--" message + HLF_CM, ///< Mode (e.g., "-- INSERT --") + HLF_N, ///< line number for ":number" and ":#" commands + HLF_LNA, ///< LineNrAbove + HLF_LNB, ///< LineNrBelow + HLF_CLN, ///< current line number when 'cursorline' is set + HLF_CLS, ///< current line sign column + HLF_CLF, ///< current line fold + HLF_R, ///< return to continue message and yes/no questions + HLF_S, ///< status lines + HLF_SNC, ///< status lines of not-current windows + HLF_C, ///< window split separators + HLF_VSP, ///< VertSplit + HLF_T, ///< Titles for output from ":set all", ":autocmd" etc. + HLF_V, ///< Visual mode + HLF_VNC, ///< Visual mode, autoselecting and not clipboard owner + HLF_W, ///< warning messages + HLF_WM, ///< Wildmenu highlight + HLF_FL, ///< Folded line + HLF_FC, ///< Fold column + HLF_ADD, ///< Added diff line + HLF_CHD, ///< Changed diff line + HLF_DED, ///< Deleted diff line + HLF_TXD, ///< Text Changed in diff line + HLF_SC, ///< Sign column + HLF_CONCEAL, ///< Concealed text + HLF_SPB, ///< SpellBad + HLF_SPC, ///< SpellCap + HLF_SPR, ///< SpellRare + HLF_SPL, ///< SpellLocal + HLF_PNI, ///< popup menu normal item + HLF_PSI, ///< popup menu selected item + HLF_PNK, ///< popup menu normal item "kind" + HLF_PSK, ///< popup menu selected item "kind" + HLF_PNX, ///< popup menu normal item "menu" (extra text) + HLF_PSX, ///< popup menu selected item "menu" (extra text) + HLF_PSB, ///< popup menu scrollbar + HLF_PST, ///< popup menu scrollbar thumb + HLF_TP, ///< tabpage line + HLF_TPS, ///< tabpage line selected + HLF_TPF, ///< tabpage line filler + HLF_CUC, ///< 'cursorcolumn' + HLF_CUL, ///< 'cursorline' + HLF_MC, ///< 'colorcolumn' + HLF_QFL, ///< selected quickfix line + HLF_0, ///< Whitespace + HLF_INACTIVE, ///< NormalNC: Normal text in non-current windows + HLF_MSGSEP, ///< message separator line + HLF_NFLOAT, ///< Floating window + HLF_MSG, ///< Message area + HLF_BORDER, ///< Floating window border + HLF_WBR, ///< Window bars + HLF_WBRNC, ///< Window bars of not-current windows + HLF_CU, ///< Cursor + HLF_BTITLE, ///< Float Border Title + HLF_BFOOTER, ///< Float Border Footer + HLF_COUNT, ///< MUST be the last one } hlf_T; -EXTERN const char *hlf_names[] INIT( = { - [HLF_8] = "SpecialKey", - [HLF_EOB] = "EndOfBuffer", - [HLF_TERM] = "TermCursor", - [HLF_TERMNC] = "TermCursorNC", - [HLF_AT] = "NonText", - [HLF_D] = "Directory", - [HLF_E] = "ErrorMsg", - [HLF_I] = "IncSearch", - [HLF_L] = "Search", - [HLF_LC] = "CurSearch", - [HLF_M] = "MoreMsg", - [HLF_CM] = "ModeMsg", - [HLF_N] = "LineNr", - [HLF_LNA] = "LineNrAbove", - [HLF_LNB] = "LineNrBelow", - [HLF_CLN] = "CursorLineNr", - [HLF_CLS] = "CursorLineSign", - [HLF_CLF] = "CursorLineFold", - [HLF_R] = "Question", - [HLF_S] = "StatusLine", - [HLF_SNC] = "StatusLineNC", - [HLF_C] = "WinSeparator", - [HLF_T] = "Title", - [HLF_V] = "Visual", - [HLF_VNC] = "VisualNC", - [HLF_VSP] = "VertSplit", - [HLF_W] = "WarningMsg", - [HLF_WM] = "WildMenu", - [HLF_FL] = "Folded", - [HLF_FC] = "FoldColumn", - [HLF_ADD] = "DiffAdd", - [HLF_CHD] = "DiffChange", - [HLF_DED] = "DiffDelete", - [HLF_TXD] = "DiffText", - [HLF_SC] = "SignColumn", - [HLF_CONCEAL] = "Conceal", - [HLF_SPB] = "SpellBad", - [HLF_SPC] = "SpellCap", - [HLF_SPR] = "SpellRare", - [HLF_SPL] = "SpellLocal", - [HLF_PNI] = "Pmenu", - [HLF_PSI] = "PmenuSel", - [HLF_PNK] = "PmenuKind", - [HLF_PSK] = "PmenuKindSel", - [HLF_PNX] = "PmenuExtra", - [HLF_PSX] = "PmenuExtraSel", - [HLF_PSB] = "PmenuSbar", - [HLF_PST] = "PmenuThumb", - [HLF_TP] = "TabLine", - [HLF_TPS] = "TabLineSel", - [HLF_TPF] = "TabLineFill", - [HLF_CUC] = "CursorColumn", - [HLF_CUL] = "CursorLine", - [HLF_MC] = "ColorColumn", - [HLF_QFL] = "QuickFixLine", - [HLF_0] = "Whitespace", - [HLF_INACTIVE] = "NormalNC", - [HLF_MSGSEP] = "MsgSeparator", - [HLF_NFLOAT] = "NormalFloat", - [HLF_MSG] = "MsgArea", - [HLF_BORDER] = "FloatBorder", - [HLF_WBR] = "WinBar", - [HLF_WBRNC] = "WinBarNC", - [HLF_CU] = "Cursor", - [HLF_BTITLE] = "FloatTitle", - [HLF_BFOOTER] = "FloatFooter", -}); - -EXTERN int highlight_attr[HLF_COUNT + 1]; // Highl. attr for each context. -EXTERN int highlight_attr_last[HLF_COUNT]; // copy for detecting changed groups -EXTERN int highlight_user[9]; // User[1-9] attributes -EXTERN int highlight_stlnc[9]; // On top of user -EXTERN int cterm_normal_fg_color INIT( = 0); -EXTERN int cterm_normal_bg_color INIT( = 0); -EXTERN RgbValue normal_fg INIT( = -1); -EXTERN RgbValue normal_bg INIT( = -1); -EXTERN RgbValue normal_sp INIT( = -1); - -EXTERN NS ns_hl_global INIT( = 0); // global highlight namespace -EXTERN NS ns_hl_win INIT( = -1); // highlight namespace for the current window -EXTERN NS ns_hl_fast INIT( = -1); // highlight namespace specified in a fast callback -EXTERN NS ns_hl_active INIT( = 0); // currently active/cached namespace - -EXTERN int *hl_attr_active INIT( = highlight_attr); - typedef enum { kHlUnknown, kHlUI, @@ -246,3 +158,5 @@ typedef struct { } ColorItem; #define COLOR_ITEM_INITIALIZER { .attr_id = -1, .link_id = -1, .version = -1, \ .is_default = false, .link_global = false } + +enum { HLATTRS_DICT_SIZE = 16, }; diff --git a/src/nvim/main.c b/src/nvim/main.c index 544196d78a..937035eace 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -26,7 +26,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/channel.h" #include "nvim/decoration.h" #include "nvim/decoration_provider.h" @@ -42,6 +41,7 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/garray.h" @@ -96,6 +96,7 @@ #include "nvim/version.h" #include "nvim/vim_defs.h" #include "nvim/window.h" +#include "nvim/winfloat.h" #ifdef MSWIN # include "nvim/os/os_win_console.h" #endif diff --git a/src/nvim/mark.h b/src/nvim/mark.h index c73c649789..990be69028 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -121,6 +121,9 @@ static inline void clearpos(pos_T *a) a->coladd = 0; } +/// Global marks (marks with file number or name) +EXTERN xfmark_T namedfm[NGLOBALMARKS] INIT( = { 0 }); + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mark.h.generated.h" #endif diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h index 67532d030f..04672a5c52 100644 --- a/src/nvim/mark_defs.h +++ b/src/nvim/mark_defs.h @@ -84,6 +84,3 @@ typedef struct xfilemark { } xfmark_T; #define INIT_XFMARK { INIT_FMARK, NULL } - -/// Global marks (marks with file number or name) -EXTERN xfmark_T namedfm[NGLOBALMARKS] INIT( = { 0 }); diff --git a/src/nvim/winfloat.h b/src/nvim/winfloat.h index 876ea9ccea..877a12a9e7 100644 --- a/src/nvim/winfloat.h +++ b/src/nvim/winfloat.h @@ -2,6 +2,17 @@ #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/macros_defs.h" + +/// NW -> 0 +/// NE -> kFloatAnchorEast +/// SW -> kFloatAnchorSouth +/// SE -> kFloatAnchorSouth | kFloatAnchorEast +EXTERN const char *const float_anchor_str[] INIT( = { "NW", "NE", "SW", "SE" }); + +/// Keep in sync with FloatRelative in buffer_defs.h +EXTERN const char *const float_relative_str[] +INIT( = { "editor", "win", "cursor", "mouse" }); #ifdef INCLUDE_GENERATED_DECLARATIONS # include "winfloat.h.generated.h" -- cgit From c8e37a589a4bffbdf374a5893ef269d2fe233ce6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 19:52:23 +0800 Subject: refactor(IWYU): move typedefs out of globals.h (#26322) --- src/clint.py | 11 ----- src/nvim/autocmd.h | 57 +++++++++++++++++++++----- src/nvim/eval.c | 1 + src/nvim/eval.h | 7 ++-- src/nvim/eval/encode.c | 1 + src/nvim/eval/typval_defs.h | 15 ++++--- src/nvim/ex_cmds.h | 33 +++++++-------- src/nvim/ex_docmd.h | 2 +- src/nvim/ex_eval_defs.h | 8 ++-- src/nvim/file_search.h | 16 ++++---- src/nvim/fileio.h | 63 +++++++++++++++-------------- src/nvim/getchar.h | 3 +- src/nvim/globals.h | 97 +-------------------------------------------- src/nvim/hashtab_defs.h | 12 +++--- src/nvim/insexpand.h | 3 +- src/nvim/mapping_defs.h | 3 +- src/nvim/mbyte_defs.h | 15 +++---- src/nvim/message.h | 3 +- src/nvim/mouse.h | 2 +- src/nvim/move.h | 4 +- src/nvim/normal_defs.h | 3 +- src/nvim/os/os_defs.h | 28 +++++++++++++ src/nvim/pos_defs.h | 16 +++----- src/nvim/regexp_defs.h | 22 +++++----- src/nvim/search.h | 94 ++++++++++++++++++++++++------------------- src/nvim/spell.h | 5 +-- src/nvim/spell_defs.h | 11 ++--- src/nvim/syntax.h | 43 ++++++++++---------- src/nvim/textobject.h | 2 +- src/nvim/undo_defs.h | 3 +- src/nvim/vim_defs.h | 44 +++++++++++++++++--- src/nvim/window.h | 6 ++- 32 files changed, 322 insertions(+), 311 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index a45969af31..9b946998c9 100755 --- a/src/clint.py +++ b/src/clint.py @@ -931,11 +931,7 @@ def CheckIncludes(filename, lines, error): "src/nvim/event/stream.h", "src/nvim/event/time.h", "src/nvim/event/wstream.h", - "src/nvim/ex_cmds.h", - "src/nvim/ex_docmd.h", "src/nvim/extmark.h", - "src/nvim/file_search.h", - "src/nvim/fileio.h", "src/nvim/fold.h", "src/nvim/garray.h", "src/nvim/getchar.h", @@ -944,14 +940,11 @@ def CheckIncludes(filename, lines, error): "src/nvim/highlight.h", "src/nvim/highlight_group.h", "src/nvim/input.h", - "src/nvim/insexpand.h", "src/nvim/keycodes.h", "src/nvim/log.h", "src/nvim/lua/executor.h", "src/nvim/main.h", "src/nvim/mark.h", - "src/nvim/mouse.h", - "src/nvim/move.h", "src/nvim/msgpack_rpc/channel.h", "src/nvim/msgpack_rpc/channel_defs.h", "src/nvim/msgpack_rpc/helpers.h", @@ -965,10 +958,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/path.h", "src/nvim/plines.h", "src/nvim/popupmenu.h", - "src/nvim/search.h", - "src/nvim/spell.h", - "src/nvim/syntax.h", - "src/nvim/textobject.h", "src/nvim/tui/input.h", "src/nvim/ui.h", "src/nvim/viml/parser/expressions.h", diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index 259a56cf5c..8ff4d75ddf 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -27,18 +27,57 @@ EXTERN win_T *last_cursormoved_win INIT( = NULL); /// For CursorMoved event, only used when last_cursormoved_win == curwin EXTERN pos_T last_cursormoved INIT( = { 0, 0, 0 }); -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "autocmd.h.generated.h" -#endif +EXTERN bool autocmd_busy INIT( = false); ///< Is apply_autocmds() busy? +EXTERN int autocmd_no_enter INIT( = false); ///< *Enter autocmds disabled +EXTERN int autocmd_no_leave INIT( = false); ///< *Leave autocmds disabled +EXTERN bool did_filetype INIT( = false); ///< FileType event found +/// value for did_filetype when starting to execute autocommands +EXTERN bool keep_filetype INIT( = false); + +/// When deleting the current buffer, another one must be loaded. +/// If we know which one is preferred, au_new_curbuf is set to it. +EXTERN bufref_T au_new_curbuf INIT( = { NULL, 0, 0 }); + +// When deleting a buffer/window and autocmd_busy is true, do not free the +// buffer/window. but link it in the list starting with +// au_pending_free_buf/ap_pending_free_win, using b_next/w_next. +// Free the buffer/window when autocmd_busy is being set to false. +EXTERN buf_T *au_pending_free_buf INIT( = NULL); +EXTERN win_T *au_pending_free_win INIT( = NULL); + +EXTERN char *autocmd_fname INIT( = NULL); ///< fname for on cmdline +EXTERN bool autocmd_fname_full INIT( = false); ///< autocmd_fname is full path +EXTERN int autocmd_bufnr INIT( = 0); ///< fnum for on cmdline +EXTERN char *autocmd_match INIT( = NULL); ///< name for on cmdline +EXTERN bool did_cursorhold INIT( = false); ///< set when CursorHold t'gerd -#define AUGROUP_DEFAULT (-1) // default autocmd group -#define AUGROUP_ERROR (-2) // erroneous autocmd group -#define AUGROUP_ALL (-3) // all autocmd groups -#define AUGROUP_DELETED (-4) // all autocmd groups -// #define AUGROUP_NS -5 // TODO(tjdevries): Support namespaced based augroups +typedef struct { + win_T *auc_win; ///< Window used in aucmd_prepbuf(). When not NULL the + ///< window has been allocated. + bool auc_win_used; ///< This auc_win is being used. +} aucmdwin_T; -#define BUFLOCAL_PAT_LEN 25 +/// When executing autocommands for a buffer that is not in any window, a +/// special window is created to handle the side effects. When autocommands +/// nest we may need more than one. +EXTERN kvec_t(aucmdwin_T) aucmd_win_vec INIT( = KV_INITIAL_VALUE); +#define aucmd_win (aucmd_win_vec.items) +#define AUCMD_WIN_COUNT ((int)aucmd_win_vec.size) + +enum { + AUGROUP_DEFAULT = -1, ///< default autocmd group + AUGROUP_ERROR = -2, ///< erroneous autocmd group + AUGROUP_ALL = -3, ///< all autocmd groups + AUGROUP_DELETED = -4, ///< all autocmd groups + // AUGROUP_NS = -5, // TODO(tjdevries): Support namespaced based augroups +}; + +enum { BUFLOCAL_PAT_LEN = 25, }; /// Iterates over all the events for auto commands #define FOR_ALL_AUEVENTS(event) \ for (event_T event = (event_T)0; (int)event < (int)NUM_EVENTS; event = (event_T)((int)event + 1)) // NOLINT + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "autocmd.h.generated.h" +#endif diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a43ca3d78a..de36bf016f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14,6 +14,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" +#include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/channel.h" diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 1fc2891917..7306645cc3 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -4,17 +4,18 @@ #include #include -#include "nvim/buffer_defs.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/channel.h" -#include "nvim/cmdexpand_defs.h" +#include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/event/time.h" #include "nvim/ex_cmds_defs.h" -#include "nvim/globals.h" #include "nvim/hashtab_defs.h" #include "nvim/macros_defs.h" +#include "nvim/mbyte_defs.h" // IWYU pragma: keep #include "nvim/os/fileio.h" #include "nvim/os/stdpaths_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep #define COPYID_INC 2 #define COPYID_MASK (~0x1) diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 8505c30fad..38be10dbaf 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -21,6 +21,7 @@ #include "nvim/eval/typval_encode.h" #include "nvim/garray.h" #include "nvim/gettext.h" +#include "nvim/globals.h" #include "nvim/hashtab.h" #include "nvim/macros_defs.h" #include "nvim/math.h" diff --git a/src/nvim/eval/typval_defs.h b/src/nvim/eval/typval_defs.h index c6bd11ccdb..a6a0282fad 100644 --- a/src/nvim/eval/typval_defs.h +++ b/src/nvim/eval/typval_defs.h @@ -13,8 +13,10 @@ typedef int64_t varnumber_T; typedef uint64_t uvarnumber_T; -/// Refcount for dict or list that should not be freed -enum { DO_NOT_FREE_CNT = (INT_MAX / 2), }; +enum { + /// Refcount for dict or list that should not be freed + DO_NOT_FREE_CNT = (INT_MAX / 2), +}; /// Additional values for tv_list_alloc() len argument enum ListLenSpecials { @@ -291,12 +293,9 @@ typedef struct { uint64_t channel_id; /// Only used when script_id is SID_API_CLIENT. } LastSet; -/// Maximum number of function arguments -enum { MAX_FUNC_ARGS = 20, }; -/// Short variable name length -enum { VAR_SHORT_LEN = 20, }; -/// Number of fixed variables used for arguments -enum { FIXVAR_CNT = 12, }; +enum { MAX_FUNC_ARGS = 20, }; ///< Maximum number of function arguments +enum { VAR_SHORT_LEN = 20, }; ///< Short variable name length +enum { FIXVAR_CNT = 12, }; ///< Number of fixed variables used for arguments /// Structure to hold info for a function that is currently being executed. typedef struct funccall_S funccall_T; diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index de13f03197..011d42c6d9 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -1,27 +1,28 @@ #pragma once -#include - #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: export -#include "nvim/os/time.h" +#include "nvim/os/time_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep -// flags for do_ecmd() -#define ECMD_HIDE 0x01 // don't free the current buffer -#define ECMD_SET_HELP 0x02 // set b_help flag of (new) buffer before - // opening file -#define ECMD_OLDBUF 0x04 // use existing buffer if it exists -#define ECMD_FORCEIT 0x08 // ! used in Ex command -#define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list -#define ECMD_ALTBUF 0x20 // like ECMD_ADDBUF and set the alternate file -#define ECMD_NOWINENTER 0x40 // do not trigger BufWinEnter +/// flags for do_ecmd() +enum { + ECMD_HIDE = 0x01, ///< don't free the current buffer + ECMD_SET_HELP = 0x02, ///< set b_help flag of (new) buffer before opening file + ECMD_OLDBUF = 0x04, ///< use existing buffer if it exists + ECMD_FORCEIT = 0x08, ///< ! used in Ex command + ECMD_ADDBUF = 0x10, ///< don't edit, just add to buffer list + ECMD_ALTBUF = 0x20, ///< like ECMD_ADDBUF and set the alternate file + ECMD_NOWINENTER = 0x40, ///< do not trigger BufWinEnter +}; -// for lnum argument in do_ecmd() -#define ECMD_LASTL 0 // use last position in loaded file -#define ECMD_LAST (-1) // use last position in all files -#define ECMD_ONE 1 // use first line +/// for lnum argument in do_ecmd() +enum { + ECMD_LASTL = 0, ///< use last position in loaded file + ECMD_LAST = -1, ///< use last position in all files + ECMD_ONE = 1, ///< use first line +}; /// Previous :substitute replacement string definition typedef struct { diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index 698153e8df..ce23b9f464 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -6,8 +6,8 @@ #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/getchar_defs.h" -#include "nvim/globals.h" #include "nvim/types_defs.h" // IWYU pragma: keep +#include "nvim/vim_defs.h" // IWYU pragma: keep /// flags for do_cmdline() enum { diff --git a/src/nvim/ex_eval_defs.h b/src/nvim/ex_eval_defs.h index c7231bb315..3f5e510a20 100644 --- a/src/nvim/ex_eval_defs.h +++ b/src/nvim/ex_eval_defs.h @@ -13,9 +13,11 @@ struct eslist_elem { eslist_T *next; ///< next element on the list }; -/// For conditional commands a stack is kept of nested conditionals. -/// When cs_idx < 0, there is no conditional command. -enum { CSTACK_LEN = 50, }; +enum { + /// For conditional commands a stack is kept of nested conditionals. + /// When cs_idx < 0, there is no conditional command. + CSTACK_LEN = 50, +}; typedef struct { int cs_flags[CSTACK_LEN]; ///< CSF_ flags diff --git a/src/nvim/file_search.h b/src/nvim/file_search.h index d4b5c5d352..a2d578a668 100644 --- a/src/nvim/file_search.h +++ b/src/nvim/file_search.h @@ -1,14 +1,14 @@ #pragma once -#include - -#include "nvim/globals.h" #include "nvim/types_defs.h" // IWYU pragma: keep - -// Flags for find_file_*() functions. -#define FINDFILE_FILE 0 // only files -#define FINDFILE_DIR 1 // only directories -#define FINDFILE_BOTH 2 // files and directories +#include "nvim/vim_defs.h" // IWYU pragma: keep + +/// Flags for find_file_*() functions. +enum { + FINDFILE_FILE = 0, ///< only files + FINDFILE_DIR = 1, ///< only directories + FINDFILE_BOTH = 2, ///< files and directories +}; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "file_search.h.generated.h" diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h index d1f6561507..32a5ec3002 100644 --- a/src/nvim/fileio.h +++ b/src/nvim/fileio.h @@ -8,44 +8,49 @@ #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/garray_defs.h" // IWYU pragma: keep -#include "nvim/globals.h" #include "nvim/os/fs_defs.h" // IWYU pragma: keep -#include "nvim/pos_defs.h" - -// Values for readfile() flags -#define READ_NEW 0x01 // read a file into a new buffer -#define READ_FILTER 0x02 // read filter output -#define READ_STDIN 0x04 // read from stdin -#define READ_BUFFER 0x08 // read from curbuf (converting stdin) -#define READ_DUMMY 0x10 // reading into a dummy buffer -#define READ_KEEP_UNDO 0x20 // keep undo info -#define READ_FIFO 0x40 // read from fifo or socket -#define READ_NOWINENTER 0x80 // do not trigger BufWinEnter -#define READ_NOFILE 0x100 // do not read a file, do trigger BufReadCmd +#include "nvim/pos_defs.h" // IWYU pragma: keep + +/// Values for readfile() flags +enum { + READ_NEW = 0x01, ///< read a file into a new buffer + READ_FILTER = 0x02, ///< read filter output + READ_STDIN = 0x04, ///< read from stdin + READ_BUFFER = 0x08, ///< read from curbuf (converting stdin) + READ_DUMMY = 0x10, ///< reading into a dummy buffer + READ_KEEP_UNDO = 0x20, ///< keep undo info + READ_FIFO = 0x40, ///< read from fifo or socket + READ_NOWINENTER = 0x80, ///< do not trigger BufWinEnter + READ_NOFILE = 0x100, ///< do not read a file, do trigger BufReadCmd +}; typedef varnumber_T (*CheckItem)(void *expr, const char *name); enum { - FIO_LATIN1 = 0x01, // convert Latin1 - FIO_UTF8 = 0x02, // convert UTF-8 - FIO_UCS2 = 0x04, // convert UCS-2 - FIO_UCS4 = 0x08, // convert UCS-4 - FIO_UTF16 = 0x10, // convert UTF-16 - FIO_ENDIAN_L = 0x80, // little endian - FIO_NOCONVERT = 0x2000, // skip encoding conversion - FIO_UCSBOM = 0x4000, // check for BOM at start of file - FIO_ALL = -1, // allow all formats + FIO_LATIN1 = 0x01, ///< convert Latin1 + FIO_UTF8 = 0x02, ///< convert UTF-8 + FIO_UCS2 = 0x04, ///< convert UCS-2 + FIO_UCS4 = 0x08, ///< convert UCS-4 + FIO_UTF16 = 0x10, ///< convert UTF-16 + FIO_ENDIAN_L = 0x80, ///< little endian + FIO_NOCONVERT = 0x2000, ///< skip encoding conversion + FIO_UCSBOM = 0x4000, ///< check for BOM at start of file + FIO_ALL = -1, ///< allow all formats }; -// When converting, a read() or write() may leave some bytes to be converted -// for the next call. The value is guessed... -#define CONV_RESTLEN 30 +enum { + /// When converting, a read() or write() may leave some bytes to be converted + /// for the next call. The value is guessed... + CONV_RESTLEN = 30, +}; -#define WRITEBUFSIZE 8192 // size of normal write buffer +enum { WRITEBUFSIZE = 8192, }; ///< size of normal write buffer -// We have to guess how much a sequence of bytes may expand when converting -// with iconv() to be able to allocate a buffer. -#define ICONV_MULT 8 +enum { + /// We have to guess how much a sequence of bytes may expand when converting + /// with iconv() to be able to allocate a buffer. + ICONV_MULT = 8, +}; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "fileio.h.generated.h" diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h index 177a021706..e1bc64bfee 100644 --- a/src/nvim/getchar.h +++ b/src/nvim/getchar.h @@ -15,8 +15,7 @@ typedef enum { FLUSH_INPUT, ///< flush typebuf and inchar() input } flush_buffers_T; -/// Maximum number of streams to read script from -enum { NSCRIPT = 15, }; +enum { NSCRIPT = 15, }; ///< Maximum number of streams to read script from /// Streams to read script from extern FileDescriptor *scriptin[NSCRIPT]; diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 270ffe4fa0..1299aa12e5 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -103,34 +103,6 @@ EXTERN struct nvim_stats_s { EXTERN int Rows INIT( = DFLT_ROWS); // nr of rows in the screen EXTERN int Columns INIT( = DFLT_COLS); // nr of columns in the screen -// We use 64-bit file functions here, if available. E.g. ftello() returns -// off_t instead of long, which helps if long is 32 bit and off_t is 64 bit. -// We assume that when fseeko() is available then ftello() is too. -// Note that Windows has different function names. -#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) -typedef __int64 off_T; -# ifdef __MINGW32__ -# define vim_lseek lseek64 -# define vim_fseek fseeko64 -# define vim_ftell ftello64 -# else -# define vim_lseek _lseeki64 -# define vim_fseek _fseeki64 -# define vim_ftell _ftelli64 -# endif -#else -typedef off_t off_T; -# ifdef HAVE_FSEEKO -# define vim_lseek lseek -# define vim_ftell ftello -# define vim_fseek fseeko -# else -# define vim_lseek lseek -# define vim_ftell ftell -# define vim_fseek(a, b, c) fseek(a, (long)b, c) -# endif -#endif - // When vgetc() is called, it sets mod_mask to the set of modifiers that are // held down based on the MOD_MASK_* symbols that are read first. EXTERN int mod_mask INIT( = 0); // current key modifiers @@ -370,24 +342,7 @@ EXTERN bool did_check_timestamps INIT( = false); // did check timestamps // recently EXTERN int no_check_timestamps INIT( = 0); // Don't check timestamps -EXTERN bool autocmd_busy INIT( = false); // Is apply_autocmds() busy? -EXTERN int autocmd_no_enter INIT( = false); // *Enter autocmds disabled -EXTERN int autocmd_no_leave INIT( = false); // *Leave autocmds disabled EXTERN int modified_was_set; // did ":set modified" -EXTERN bool did_filetype INIT( = false); // FileType event found -// value for did_filetype when starting to execute autocommands -EXTERN bool keep_filetype INIT( = false); - -// When deleting the current buffer, another one must be loaded. -// If we know which one is preferred, au_new_curbuf is set to it. -EXTERN bufref_T au_new_curbuf INIT( = { NULL, 0, 0 }); - -// When deleting a buffer/window and autocmd_busy is true, do not free the -// buffer/window. but link it in the list starting with -// au_pending_free_buf/ap_pending_free_win, using b_next/w_next. -// Free the buffer/window when autocmd_busy is being set to false. -EXTERN buf_T *au_pending_free_buf INIT( = NULL); -EXTERN win_T *au_pending_free_win INIT( = NULL); // Mouse coordinates, set by handle_mouse_event() EXTERN int mouse_grid; @@ -426,19 +381,6 @@ EXTERN win_T *prevwin INIT( = NULL); // previous window EXTERN win_T *curwin; // currently active window -typedef struct { - win_T *auc_win; ///< Window used in aucmd_prepbuf(). When not NULL the - ///< window has been allocated. - bool auc_win_used; ///< This auc_win is being used. -} aucmdwin_T; - -/// When executing autocommands for a buffer that is not in any window, a -/// special window is created to handle the side effects. When autocommands -/// nest we may need more than one. -EXTERN kvec_t(aucmdwin_T) aucmd_win_vec INIT( = KV_INITIAL_VALUE); -#define aucmd_win (aucmd_win_vec.items) -#define AUCMD_WIN_COUNT ((int)aucmd_win_vec.size) - // The window layout is kept in a tree of frames. topframe points to the top // of the tree. EXTERN frame_T *topframe; // top of the window frame tree @@ -758,11 +700,6 @@ EXTERN char last_mode[MODE_MAX_LENGTH] INIT( = "n"); EXTERN char *last_cmdline INIT( = NULL); // last command line (for ":) EXTERN char *repeat_cmdline INIT( = NULL); // command line for "." EXTERN char *new_last_cmdline INIT( = NULL); // new value for last_cmdline -EXTERN char *autocmd_fname INIT( = NULL); // fname for on cmdline -EXTERN bool autocmd_fname_full INIT( = false); // autocmd_fname is full path -EXTERN int autocmd_bufnr INIT( = 0); // fnum for on cmdline -EXTERN char *autocmd_match INIT( = NULL); // name for on cmdline -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() @@ -1051,39 +988,7 @@ EXTERN bool headless_mode INIT(= false); // uncrustify:on -/// Used to track the status of external functions. -/// Currently only used for iconv(). -typedef enum { - kUnknown, - kWorking, - kBroken, -} WorkingStatus; - -/// The scope of a working-directory command like `:cd`. -/// -/// Scopes are enumerated from lowest to highest. When adding a scope make sure -/// to update all functions using scopes as well, such as the implementation of -/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes -/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead. -typedef enum { - kCdScopeInvalid = -1, - kCdScopeWindow, ///< Affects one window. - kCdScopeTabpage, ///< Affects one tab page. - kCdScopeGlobal, ///< Affects the entire Nvim instance. -} CdScope; - -#define MIN_CD_SCOPE kCdScopeWindow -#define MAX_CD_SCOPE kCdScopeGlobal - -/// What caused the current directory to change. -typedef enum { - kCdCauseOther = -1, - kCdCauseManual, ///< Using `:cd`, `:tcd`, `:lcd` or `chdir()`. - kCdCauseWindow, ///< Switching to another window. - kCdCauseAuto, ///< On 'autochdir'. -} CdCause; - -// Only filled for Win32. +/// Only filled for Win32. EXTERN char windowsVersion[20] INIT( = { 0 }); /// While executing a regexp and set to OPTION_MAGIC_ON or OPTION_MAGIC_OFF this diff --git a/src/nvim/hashtab_defs.h b/src/nvim/hashtab_defs.h index 089838fcae..8888eab972 100644 --- a/src/nvim/hashtab_defs.h +++ b/src/nvim/hashtab_defs.h @@ -34,11 +34,13 @@ typedef struct hashitem_S { char *hi_key; } hashitem_T; -/// Initial size for a hashtable. -/// Our items are relatively small and growing is expensive, thus start with 16. -/// Must be a power of 2. -/// This allows for storing 10 items (2/3 of 16) before a resize is needed. -enum { HT_INIT_SIZE = 16, }; +enum { + /// Initial size for a hashtable. + /// Our items are relatively small and growing is expensive, thus start with 16. + /// Must be a power of 2. + /// This allows for storing 10 items (2/3 of 16) before a resize is needed. + HT_INIT_SIZE = 16, +}; /// An array-based hashtable. /// diff --git a/src/nvim/insexpand.h b/src/nvim/insexpand.h index 121d5568ff..b880e64ea4 100644 --- a/src/nvim/insexpand.h +++ b/src/nvim/insexpand.h @@ -1,10 +1,9 @@ #pragma once -#include "nvim/macros_defs.h" #include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -#include "nvim/vim_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "insexpand.h.generated.h" diff --git a/src/nvim/mapping_defs.h b/src/nvim/mapping_defs.h index 6691c5ac3b..4f0334c226 100644 --- a/src/nvim/mapping_defs.h +++ b/src/nvim/mapping_defs.h @@ -5,8 +5,7 @@ #include "nvim/eval/typval_defs.h" #include "nvim/types_defs.h" -/// Maximum length of key sequence to be mapped. -enum { MAXMAPLEN = 50, }; +enum { MAXMAPLEN = 50, }; ///< Maximum length of key sequence to be mapped. /// Structure used for mappings and abbreviations. typedef struct mapblock mapblock_T; diff --git a/src/nvim/mbyte_defs.h b/src/nvim/mbyte_defs.h index 2904047223..efb4f558a6 100644 --- a/src/nvim/mbyte_defs.h +++ b/src/nvim/mbyte_defs.h @@ -4,13 +4,14 @@ #include "nvim/iconv_defs.h" -/// Maximum number of bytes in a multi-byte character. It can be one 32-bit -/// character of up to 6 bytes, or one 16-bit character of up to three bytes -/// plus six following composing characters of three bytes each. -enum { MB_MAXBYTES = 21, }; - -/// max length of an unicode char -enum { MB_MAXCHAR = 6, }; +enum { + /// Maximum number of bytes in a multi-byte character. It can be one 32-bit + /// character of up to 6 bytes, or one 16-bit character of up to three bytes + /// plus six following composing characters of three bytes each. + MB_MAXBYTES = 21, + /// max length of an unicode char + MB_MAXCHAR = 6, +}; /// properties used in enc_canon_table[] (first three mutually exclusive) enum { diff --git a/src/nvim/message.h b/src/nvim/message.h index adbb40277b..904fb2d3ad 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -30,8 +30,7 @@ enum { VIM_DISCARDALL = 6, }; -/// special attribute addition: Put message in history -enum { MSG_HIST = 0x1000, }; +enum { MSG_HIST = 0x1000, }; ///< special attribute addition: Put message in history typedef struct { String text; diff --git a/src/nvim/mouse.h b/src/nvim/mouse.h index 928b3e360b..d787b8ff57 100644 --- a/src/nvim/mouse.h +++ b/src/nvim/mouse.h @@ -4,7 +4,7 @@ #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/normal_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -#include "nvim/vim_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep /// jump_to_mouse() returns one of first five these values, possibly with /// some of the other five added. diff --git a/src/nvim/move.h b/src/nvim/move.h index ab8fb2b386..f48de6987b 100644 --- a/src/nvim/move.h +++ b/src/nvim/move.h @@ -1,11 +1,9 @@ #pragma once -#include - #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -#include "nvim/vim_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "move.h.generated.h" diff --git a/src/nvim/normal_defs.h b/src/nvim/normal_defs.h index 060c1057f9..6ea6660a8b 100644 --- a/src/nvim/normal_defs.h +++ b/src/nvim/normal_defs.h @@ -70,6 +70,5 @@ enum { REPLACE_NL_NCHAR = -2, }; -/// columns needed by shown command -enum { SHOWCMD_COLS = 10, }; +enum { SHOWCMD_COLS = 10, }; ///< columns needed by shown command enum { SHOWCMD_BUFLEN = SHOWCMD_COLS + 1 + 30, }; diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 12de55a227..db575e005a 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -113,3 +113,31 @@ && (defined(S_ISCHR) || defined(S_IFCHR)) # define OPEN_CHR_FILES #endif + +// We use 64-bit file functions here, if available. E.g. ftello() returns +// off_t instead of long, which helps if long is 32 bit and off_t is 64 bit. +// We assume that when fseeko() is available then ftello() is too. +// Note that Windows has different function names. +#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) +typedef __int64 off_T; +# ifdef __MINGW32__ +# define vim_lseek lseek64 +# define vim_fseek fseeko64 +# define vim_ftell ftello64 +# else +# define vim_lseek _lseeki64 +# define vim_fseek _fseeki64 +# define vim_ftell _ftelli64 +# endif +#else +typedef off_t off_T; +# ifdef HAVE_FSEEKO +# define vim_lseek lseek +# define vim_ftell ftello +# define vim_fseek fseeko +# else +# define vim_lseek lseek +# define vim_ftell ftell +# define vim_fseek(a, b, c) fseek(a, (long)b, c) +# endif +#endif diff --git a/src/nvim/pos_defs.h b/src/nvim/pos_defs.h index 98a1762a5c..a9816c6a66 100644 --- a/src/nvim/pos_defs.h +++ b/src/nvim/pos_defs.h @@ -12,19 +12,15 @@ typedef int colnr_T; /// Format used to print values which have colnr_T type #define PRIdCOLNR "d" -/// Maximal (invalid) line number -enum { MAXLNUM = 0x7fffffff, }; +enum { MAXLNUM = 0x7fffffff, }; ///< Maximal (invalid) line number -/// Maximal column number -/// MAXCOL used to be INT_MAX, but with 64 bit ints that results in running -/// out of memory when trying to allocate a very long line. -enum { MAXCOL = 0x7fffffff, }; +// MAXCOL used to be INT_MAX, but with 64 bit ints that results in running +// out of memory when trying to allocate a very long line. +enum { MAXCOL = 0x7fffffff, }; ///< Maximal column number -/// Minimum line number -enum { MINLNUM = 1, }; +enum { MINLNUM = 1, }; ///< Minimum line number -/// Minimum column number -enum { MINCOL = 1, }; +enum { MINCOL = 1, }; ///< Minimum column number /// position in file or buffer typedef struct { diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index 079f3b6929..31bc0e86e8 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -33,18 +33,22 @@ typedef enum { MAGIC_ALL = 4, ///< "\v" very magic } magic_T; -/// The number of sub-matches is limited to 10. -/// The first one (index 0) is the whole match, referenced with "\0". -/// The second one (index 1) is the first sub-match, referenced with "\1". -/// This goes up to the tenth (index 9), referenced with "\9". -enum { NSUBEXP = 10, }; +enum { + /// The number of sub-matches is limited to 10. + /// The first one (index 0) is the whole match, referenced with "\0". + /// The second one (index 1) is the first sub-match, referenced with "\1". + /// This goes up to the tenth (index 9), referenced with "\9". + NSUBEXP = 10, +}; -/// In the NFA engine: how many braces are allowed. -/// TODO(RE): Use dynamic memory allocation instead of static, like here -enum { NFA_MAX_BRACES = 20, }; +enum { + /// In the NFA engine: how many braces are allowed. + /// TODO(RE): Use dynamic memory allocation instead of static, like here + NFA_MAX_BRACES = 20, +}; -/// In the NFA engine: how many states are allowed. enum { + /// In the NFA engine: how many states are allowed. NFA_MAX_STATES = 100000, NFA_TOO_EXPENSIVE = -1, }; diff --git a/src/nvim/search.h b/src/nvim/search.h index 48ca555e7f..12553c8e74 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -3,61 +3,73 @@ #include #include -#include "nvim/buffer_defs.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/normal_defs.h" // IWYU pragma: keep #include "nvim/os/time_defs.h" #include "nvim/pos_defs.h" #include "nvim/regexp_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" -#include "nvim/vim_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep -// Values for the find_pattern_in_path() function args 'type' and 'action': -#define FIND_ANY 1 -#define FIND_DEFINE 2 -#define CHECK_PATH 3 +/// Values for the find_pattern_in_path() function args 'type' and 'action': +enum { + FIND_ANY = 1, + FIND_DEFINE = 2, + CHECK_PATH = 3, +}; -#define ACTION_SHOW 1 -#define ACTION_GOTO 2 -#define ACTION_SPLIT 3 -#define ACTION_SHOW_ALL 4 -#define ACTION_EXPAND 5 +enum { + ACTION_SHOW = 1, + ACTION_GOTO = 2, + ACTION_SPLIT = 3, + ACTION_SHOW_ALL = 4, + ACTION_EXPAND = 5, +}; -// Values for 'options' argument in do_search() and searchit() -#define SEARCH_REV 0x01 ///< go in reverse of previous dir. -#define SEARCH_ECHO 0x02 ///< echo the search command and handle options -#define SEARCH_MSG 0x0c ///< give messages (yes, it's not 0x04) -#define SEARCH_NFMSG 0x08 ///< give all messages except not found -#define SEARCH_OPT 0x10 ///< interpret optional flags -#define SEARCH_HIS 0x20 ///< put search pattern in history -#define SEARCH_END 0x40 ///< put cursor at end of match -#define SEARCH_NOOF 0x80 ///< don't add offset to position -#define SEARCH_START 0x100 ///< start search without col offset -#define SEARCH_MARK 0x200 ///< set previous context mark -#define SEARCH_KEEP 0x400 ///< keep previous search pattern -#define SEARCH_PEEK 0x800 ///< peek for typed char, cancel search -#define SEARCH_COL 0x1000 ///< start at specified column instead of zero +/// Values for "options" argument in do_search() and searchit() +enum { + SEARCH_REV = 0x01, ///< go in reverse of previous dir. + SEARCH_ECHO = 0x02, ///< echo the search command and handle options + SEARCH_MSG = 0x0c, ///< give messages (yes, it's not 0x04) + SEARCH_NFMSG = 0x08, ///< give all messages except not found + SEARCH_OPT = 0x10, ///< interpret optional flags + SEARCH_HIS = 0x20, ///< put search pattern in history + SEARCH_END = 0x40, ///< put cursor at end of match + SEARCH_NOOF = 0x80, ///< don't add offset to position + SEARCH_START = 0x100, ///< start search without col offset + SEARCH_MARK = 0x200, ///< set previous context mark + SEARCH_KEEP = 0x400, ///< keep previous search pattern + SEARCH_PEEK = 0x800, ///< peek for typed char, cancel search + SEARCH_COL = 0x1000, ///< start at specified column instead of zero +}; -// Values for flags argument for findmatchlimit() -#define FM_BACKWARD 0x01 // search backwards -#define FM_FORWARD 0x02 // search forwards -#define FM_BLOCKSTOP 0x04 // stop at start/end of block -#define FM_SKIPCOMM 0x08 // skip comments +/// Values for flags argument for findmatchlimit() +enum { + FM_BACKWARD = 0x01, ///< search backwards + FM_FORWARD = 0x02, ///< search forwards + FM_BLOCKSTOP = 0x04, ///< stop at start/end of block + FM_SKIPCOMM = 0x08, ///< skip comments +}; -// Values for sub_cmd and which_pat argument for search_regcomp() -// Also used for which_pat argument for searchit() -#define RE_SEARCH 0 // save/use pat in/from search_pattern -#define RE_SUBST 1 // save/use pat in/from subst_pattern -#define RE_BOTH 2 // save pat in both patterns -#define RE_LAST 2 // use last used pattern if "pat" is NULL +/// Values for sub_cmd and which_pat argument for search_regcomp() +/// Also used for which_pat argument for searchit() +enum { + RE_SEARCH = 0, ///< save/use pat in/from search_pattern + RE_SUBST = 1, ///< save/use pat in/from subst_pattern + RE_BOTH = 2, ///< save pat in both patterns + RE_LAST = 2, ///< use last used pattern if "pat" is NULL +}; // Values for searchcount() -#define SEARCH_STAT_DEF_TIMEOUT 40 -#define SEARCH_STAT_DEF_MAX_COUNT 99 -#define SEARCH_STAT_BUF_LEN 12 +enum { SEARCH_STAT_DEF_TIMEOUT = 40, }; +enum { SEARCH_STAT_DEF_MAX_COUNT = 99, }; +enum { SEARCH_STAT_BUF_LEN = 12, }; -/// Maximum number of characters that can be fuzzy matched -#define MAX_FUZZY_MATCHES 256 +enum { + /// Maximum number of characters that can be fuzzy matched + MAX_FUZZY_MATCHES = 256, +}; /// Structure containing offset definition for the last search pattern /// diff --git a/src/nvim/spell.h b/src/nvim/spell.h index f3977fdaf2..43ba00e901 100644 --- a/src/nvim/spell.h +++ b/src/nvim/spell.h @@ -1,11 +1,8 @@ #pragma once -#include - #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep -#include "nvim/globals.h" #include "nvim/spell_defs.h" // IWYU pragma: export -#include "nvim/vim_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep /// First language that is loaded, start of the linked list of loaded languages. extern slang_T *first_lang; diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index dfa399750f..6293bc314b 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -8,12 +8,13 @@ #include "nvim/hashtab_defs.h" #include "nvim/regexp_defs.h" -/// Assume max. word len is this many bytes. -/// Some places assume a word length fits in a byte, thus it can't be above 255. -enum { MAXWLEN = 254, }; +enum { + /// Assume max. word len is this many bytes. + /// Some places assume a word length fits in a byte, thus it can't be above 255. + MAXWLEN = 254, +}; -/// Number of regions supported. -enum { MAXREGIONS = 8, }; +enum { MAXREGIONS = 8, }; ///< Number of regions supported. /// Type used for indexes in the word tree need to be at least 4 bytes. If int /// is 8 bytes we could use something smaller, but what? diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h index 4e9c7a27dc..b9065acf7d 100644 --- a/src/nvim/syntax.h +++ b/src/nvim/syntax.h @@ -1,33 +1,32 @@ #pragma once -#include - #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep -#include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/syntax_defs.h" // IWYU pragma: export -#define HL_CONTAINED 0x01 // not used on toplevel -#define HL_TRANSP 0x02 // has no highlighting -#define HL_ONELINE 0x04 // match within one line only -#define HL_HAS_EOL 0x08 // end pattern that matches with $ -#define HL_SYNC_HERE 0x10 // sync point after this item (syncing only) -#define HL_SYNC_THERE 0x20 // sync point at current line (syncing only) -#define HL_MATCH 0x40 // use match ID instead of item ID -#define HL_SKIPNL 0x80 // nextgroup can skip newlines -#define HL_SKIPWHITE 0x100 // nextgroup can skip white space -#define HL_SKIPEMPTY 0x200 // nextgroup can skip empty lines -#define HL_KEEPEND 0x400 // end match always kept -#define HL_EXCLUDENL 0x800 // exclude NL from match -#define HL_DISPLAY 0x1000 // only used for displaying, not syncing -#define HL_FOLD 0x2000 // define fold -#define HL_EXTEND 0x4000 // ignore a keepend -#define HL_MATCHCONT 0x8000 // match continued from previous line -#define HL_TRANS_CONT 0x10000 // transparent item without contains arg -#define HL_CONCEAL 0x20000 // can be concealed -#define HL_CONCEALENDS 0x40000 // can be concealed +enum { + HL_CONTAINED = 0x01, ///< not used on toplevel + HL_TRANSP = 0x02, ///< has no highlighting + HL_ONELINE = 0x04, ///< match within one line only + HL_HAS_EOL = 0x08, ///< end pattern that matches with $ + HL_SYNC_HERE = 0x10, ///< sync point after this item (syncing only) + HL_SYNC_THERE = 0x20, ///< sync point at current line (syncing only) + HL_MATCH = 0x40, ///< use match ID instead of item ID + HL_SKIPNL = 0x80, ///< nextgroup can skip newlines + HL_SKIPWHITE = 0x100, ///< nextgroup can skip white space + HL_SKIPEMPTY = 0x200, ///< nextgroup can skip empty lines + HL_KEEPEND = 0x400, ///< end match always kept + HL_EXCLUDENL = 0x800, ///< exclude NL from match + HL_DISPLAY = 0x1000, ///< only used for displaying, not syncing + HL_FOLD = 0x2000, ///< define fold + HL_EXTEND = 0x4000, ///< ignore a keepend + HL_MATCHCONT = 0x8000, ///< match continued from previous line + HL_TRANS_CONT = 0x10000, ///< transparent item without contains arg + HL_CONCEAL = 0x20000, ///< can be concealed + HL_CONCEALENDS = 0x40000, ///< can be concealed +}; #define SYN_GROUP_STATIC(s) syn_check_group(S_LEN(s)) diff --git a/src/nvim/textobject.h b/src/nvim/textobject.h index a540c7c98f..735a2fec3d 100644 --- a/src/nvim/textobject.h +++ b/src/nvim/textobject.h @@ -2,7 +2,7 @@ #include "nvim/normal_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep -#include "nvim/vim_defs.h" +#include "nvim/vim_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "textobject.h.generated.h" diff --git a/src/nvim/undo_defs.h b/src/nvim/undo_defs.h index 0b78ea543f..09a9689f67 100644 --- a/src/nvim/undo_defs.h +++ b/src/nvim/undo_defs.h @@ -6,8 +6,7 @@ #include "nvim/mark_defs.h" #include "nvim/pos_defs.h" -/// Size in bytes of the hash used in the undo file. -enum { UNDO_HASH_SIZE = 32, }; +enum { UNDO_HASH_SIZE = 32, }; ///< Size in bytes of the hash used in the undo file. typedef struct u_header u_header_T; diff --git a/src/nvim/vim_defs.h b/src/nvim/vim_defs.h index faf79b1c79..155265ac42 100644 --- a/src/nvim/vim_defs.h +++ b/src/nvim/vim_defs.h @@ -15,11 +15,10 @@ # error Configure did not run properly. #endif -// bring lots of system header files -#include "nvim/os/os_defs.h" // IWYU pragma: keep - -/// length of a buffer to store a number in ASCII (64 bits binary + NUL) -enum { NUMBUFLEN = 65, }; +enum { + /// length of a buffer to store a number in ASCII (64 bits binary + NUL) + NUMBUFLEN = 65, +}; #define MAX_TYPENR 65535 @@ -32,6 +31,41 @@ typedef enum { BACKWARD_FILE = -3, } Direction; +/// Used to track the status of external functions. +/// Currently only used for iconv(). +typedef enum { + kUnknown, + kWorking, + kBroken, +} WorkingStatus; + +/// The scope of a working-directory command like `:cd`. +/// +/// Scopes are enumerated from lowest to highest. When adding a scope make sure +/// to update all functions using scopes as well, such as the implementation of +/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes +/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead. +typedef enum { + kCdScopeInvalid = -1, + kCdScopeWindow, ///< Affects one window. + kCdScopeTabpage, ///< Affects one tab page. + kCdScopeGlobal, ///< Affects the entire Nvim instance. +} CdScope; + +#define MIN_CD_SCOPE kCdScopeWindow +#define MAX_CD_SCOPE kCdScopeGlobal + +/// What caused the current directory to change. +typedef enum { + kCdCauseOther = -1, + kCdCauseManual, ///< Using `:cd`, `:tcd`, `:lcd` or `chdir()`. + kCdCauseWindow, ///< Switching to another window. + kCdCauseAuto, ///< On 'autochdir'. +} CdCause; + +// bring lots of system header files +#include "nvim/os/os_defs.h" // IWYU pragma: keep + // return values for functions #if !(defined(OK) && (OK == 1)) // OK already defined to 1 in MacOS X curses, skip this diff --git a/src/nvim/window.h b/src/nvim/window.h index 3650fef46e..d70292508a 100644 --- a/src/nvim/window.h +++ b/src/nvim/window.h @@ -38,8 +38,10 @@ enum { STATUS_HEIGHT = 1, ///< height of a status line under a window }; -/// Lowest number used for window ID. Cannot have this many windows per tab. -enum { LOWEST_WIN_ID = 1000, }; +enum { + /// Lowest number used for window ID. Cannot have this many windows per tab. + LOWEST_WIN_ID = 1000, +}; /// Set to true if 'cmdheight' was explicitly set to 0. EXTERN bool p_ch_was_zero INIT( = false); -- cgit From 884a83049b2c33e2b3b6cc5c9c7f6bf820b24a3d Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 30 Nov 2023 08:04:33 -0600 Subject: fix(tui): grow termkey's internal buffer for large escape sequences (#26309) Some escape sequences (in particular, OSC 52 paste responses) can be very large, even unbounded in length. These can easily overflow termkey's internal buffer. In order to process these long sequences, dynamically grow termkey's internal buffer. --- src/nvim/tui/input.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 639bfc0f79..7ef10c0acd 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -27,6 +27,11 @@ #define READ_STREAM_SIZE 0xfff #define KEY_BUFFER_SIZE 0xfff +/// Size of libtermkey's internal input buffer. The buffer may grow larger than +/// this when processing very long escape sequences, but will shrink back to +/// this size afterward +#define INPUT_BUFFER_SIZE 256 + static const struct kitty_key_map_entry { int key; const char *name; @@ -139,6 +144,7 @@ void tinput_init(TermInput *input, Loop *loop) input->tk = termkey_new_abstract(term, TERMKEY_FLAG_UTF8 | TERMKEY_FLAG_NOSTART); + termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE); termkey_hook_terminfo_getstr(input->tk, input->tk_ti_hook_fn, input); termkey_start(input->tk); @@ -147,7 +153,6 @@ void tinput_init(TermInput *input, Loop *loop) // setup input handle rstream_init_fd(loop, &input->read_stream, input->in_fd, READ_STREAM_SIZE); - termkey_set_buffer_size(input->tk, rbuffer_capacity(input->read_stream.buffer)); // initialize a timer handle for handling ESC with libtermkey time_watcher_init(loop, &input->timer_handle, input); @@ -691,20 +696,42 @@ static void handle_raw_buffer(TermInput *input, bool force) } // Push through libtermkey (translates to "" strings, etc.). RBUFFER_UNTIL_EMPTY(input->read_stream.buffer, ptr, len) { - size_t consumed = termkey_push_bytes(input->tk, ptr, MIN(count, len)); - // termkey_push_bytes can return (size_t)-1, so it is possible that - // `consumed > rbuffer_size(input->read_stream.buffer)`, but since tk_getkeys is - // called soon, it shouldn't happen. + const size_t size = MIN(count, len); + if (size > termkey_get_buffer_remaining(input->tk)) { + // We are processing a very long escape sequence. Increase termkey's + // internal buffer size. We don't handle out of memory situations so + // assert the result + const size_t delta = size - termkey_get_buffer_remaining(input->tk); + const size_t bufsize = termkey_get_buffer_size(input->tk); + const bool success = termkey_set_buffer_size(input->tk, MAX(bufsize + delta, bufsize * 2)); + assert(success); + } + + size_t consumed = termkey_push_bytes(input->tk, ptr, size); + + // We resize termkey's buffer when it runs out of space, so this should + // never happen assert(consumed <= rbuffer_size(input->read_stream.buffer)); rbuffer_consumed(input->read_stream.buffer, consumed); - // Process the keys now: there is no guarantee `count` will - // fit into libtermkey's input buffer. + + // Process the input buffer now for any keys tk_getkeys(input, false); + if (!(count -= consumed)) { break; } } } while (rbuffer_size(input->read_stream.buffer)); + + const size_t tk_size = termkey_get_buffer_size(input->tk); + const size_t tk_remaining = termkey_get_buffer_remaining(input->tk); + const size_t tk_count = tk_size - tk_remaining; + if (tk_count < INPUT_BUFFER_SIZE && tk_size > INPUT_BUFFER_SIZE) { + // If the termkey buffer was resized to handle a large input sequence then + // shrink it back down to its original size. + const bool success = termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE); + assert(success); + } } static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof) -- cgit From a6f26c86cb74222fe2449f8a035f29b0ee45c98e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 22:48:15 +0800 Subject: refactor(IWYU): fix includes for cmdhist.h (#26324) --- src/clint.py | 8 -------- src/nvim/cmdhist.c | 1 + src/nvim/cmdhist.h | 11 +++++------ src/nvim/diff.h | 11 ++++++----- src/nvim/drawscreen.h | 3 +-- src/nvim/eval.c | 2 +- src/nvim/ex_cmds.c | 1 + src/nvim/fold.h | 6 +++--- src/nvim/insexpand.c | 1 + src/nvim/log.h | 6 ++++-- src/nvim/main.c | 1 + src/nvim/path.c | 2 -- src/nvim/path.h | 43 ++++++++++++++++++++++--------------------- src/nvim/shada.c | 10 +++++----- src/nvim/tui/input.c | 2 ++ 15 files changed, 53 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 9b946998c9..ddd3ff7d44 100755 --- a/src/clint.py +++ b/src/clint.py @@ -910,11 +910,8 @@ def CheckIncludes(filename, lines, error): "src/nvim/channel.h", "src/nvim/charset.h", "src/nvim/cmdexpand.h", - "src/nvim/cmdhist.h", "src/nvim/decoration.h", - "src/nvim/diff.h", "src/nvim/drawline.h", - "src/nvim/drawscreen.h", "src/nvim/eval.h", "src/nvim/eval/encode.h", "src/nvim/eval/typval.h", @@ -932,7 +929,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/event/time.h", "src/nvim/event/wstream.h", "src/nvim/extmark.h", - "src/nvim/fold.h", "src/nvim/garray.h", "src/nvim/getchar.h", "src/nvim/globals.h", @@ -941,7 +937,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/highlight_group.h", "src/nvim/input.h", "src/nvim/keycodes.h", - "src/nvim/log.h", "src/nvim/lua/executor.h", "src/nvim/main.h", "src/nvim/mark.h", @@ -955,14 +950,11 @@ def CheckIncludes(filename, lines, error): "src/nvim/os/pty_conpty_win.h", "src/nvim/os/pty_process_unix.h", "src/nvim/os/pty_process_win.h", - "src/nvim/path.h", "src/nvim/plines.h", - "src/nvim/popupmenu.h", "src/nvim/tui/input.h", "src/nvim/ui.h", "src/nvim/viml/parser/expressions.h", "src/nvim/viml/parser/parser.h", - "src/nvim/window.h", ] skip_headers = [ diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index 7ebe3c34a1..9396fdac7f 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -21,6 +21,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option_vars.h" +#include "nvim/os/time.h" #include "nvim/regexp.h" #include "nvim/strings.h" #include "nvim/types_defs.h" diff --git a/src/nvim/cmdhist.h b/src/nvim/cmdhist.h index cce0f92898..489e9d283f 100644 --- a/src/nvim/cmdhist.h +++ b/src/nvim/cmdhist.h @@ -1,10 +1,10 @@ #pragma once -#include "nvim/cmdexpand_defs.h" // IWYU pragma: export +#include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" -#include "nvim/ex_cmds_defs.h" // IWYU pragma: export -#include "nvim/os/time.h" -#include "nvim/types_defs.h" +#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep +#include "nvim/os/time_defs.h" +#include "nvim/types_defs.h" // IWYU pragma: keep /// Present history tables typedef enum { @@ -17,8 +17,7 @@ typedef enum { HIST_DEBUG, ///< Debug commands. } HistoryType; -/// Number of history tables -#define HIST_COUNT (HIST_DEBUG + 1) +enum { HIST_COUNT = HIST_DEBUG + 1, }; ///< Number of history tables /// History entry definition typedef struct hist_entry { diff --git a/src/nvim/diff.h b/src/nvim/diff.h index 8b58887890..fd897498df 100644 --- a/src/nvim/diff.h +++ b/src/nvim/diff.h @@ -2,16 +2,17 @@ #include -#include "nvim/ex_cmds_defs.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" -#include "nvim/pos_defs.h" +#include "nvim/pos_defs.h" // IWYU pragma: keep // Value set from 'diffopt'. -EXTERN int diff_context INIT( = 6); // context for folds -EXTERN int diff_foldcolumn INIT( = 2); // 'foldcolumn' for diff mode +EXTERN int diff_context INIT( = 6); ///< context for folds +EXTERN int diff_foldcolumn INIT( = 2); ///< 'foldcolumn' for diff mode EXTERN bool diff_need_scrollbind INIT( = false); -EXTERN bool need_diff_redraw INIT( = false); // need to call diff_redraw() +EXTERN bool need_diff_redraw INIT( = false); ///< need to call diff_redraw() #ifdef INCLUDE_GENERATED_DECLARATIONS # include "diff.h.generated.h" diff --git a/src/nvim/drawscreen.h b/src/nvim/drawscreen.h index 565b01bcd1..b18a907ba8 100644 --- a/src/nvim/drawscreen.h +++ b/src/nvim/drawscreen.h @@ -3,7 +3,6 @@ #include #include "nvim/buffer_defs.h" -#include "nvim/drawline.h" #include "nvim/macros_defs.h" /// flags for update_screen() @@ -22,7 +21,7 @@ enum { /// ('lines' and 'rows') must not be changed. EXTERN bool updating_screen INIT( = 0); -EXTERN match_T screen_search_hl INIT( = { 0 }); // used for 'hlsearch' highlight matching +EXTERN match_T screen_search_hl INIT( = { 0 }); ///< used for 'hlsearch' highlight matching #define W_ENDCOL(wp) ((wp)->w_wincol + (wp)->w_width) #define W_ENDROW(wp) ((wp)->w_winrow + (wp)->w_height) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index de36bf016f..6786316b8e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4548,7 +4548,7 @@ bool garbage_collect(bool testing) // history items (ShaDa additional elements) if (p_hi) { - for (HistoryType i = 0; i < HIST_COUNT; i++) { + for (int i = 0; i < HIST_COUNT; i++) { const void *iter = NULL; do { histentry_T hist; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index c0aca071e2..2c51d64972 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -25,6 +25,7 @@ #include "nvim/change.h" #include "nvim/channel.h" #include "nvim/charset.h" +#include "nvim/cmdexpand_defs.h" #include "nvim/cmdhist.h" #include "nvim/cursor.h" #include "nvim/decoration.h" diff --git a/src/nvim/fold.h b/src/nvim/fold.h index 3a70c11792..efa239daa5 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -1,13 +1,13 @@ #pragma once -#include +#include // IWYU pragma: keep #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/fold_defs.h" // IWYU pragma: export #include "nvim/garray_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" -#include "nvim/pos_defs.h" -#include "nvim/types_defs.h" +#include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep EXTERN int disable_fold_update INIT( = 0); diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 4595c6913b..a59ba1b6d9 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -9,6 +9,7 @@ #include #include +#include "klib/kvec.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" diff --git a/src/nvim/log.h b/src/nvim/log.h index cac074d146..b277e09a0f 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -45,9 +45,11 @@ # define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) #endif -#if NVIM_HAS_INCLUDE("sanitizer/asan_interface.h") -# include "sanitizer/asan_interface.h" +// uncrustify:off +#if NVIM_HAS_INCLUDE() +# include // IWYU pragma: keep #endif +// uncrustify:on #ifdef INCLUDE_GENERATED_DECLARATIONS # include "log.h.generated.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index 937035eace..216e39f3e8 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -30,6 +30,7 @@ #include "nvim/decoration.h" #include "nvim/decoration_provider.h" #include "nvim/diff.h" +#include "nvim/drawline.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" diff --git a/src/nvim/path.c b/src/nvim/path.c index 100d66dfff..28de003212 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -15,9 +15,7 @@ #include "nvim/ex_docmd.h" #include "nvim/file_search.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" -#include "nvim/garray_defs.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/path.h b/src/nvim/path.h index 89f939dd02..a8eb893bb3 100644 --- a/src/nvim/path.h +++ b/src/nvim/path.h @@ -2,32 +2,33 @@ #include // IWYU pragma: keep -#include "nvim/func_attr.h" #include "nvim/garray_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -// Flags for expand_wildcards() -#define EW_DIR 0x01 // include directory names -#define EW_FILE 0x02 // include file names -#define EW_NOTFOUND 0x04 // include not found names -#define EW_ADDSLASH 0x08 // append slash to directory name -#define EW_KEEPALL 0x10 // keep all matches -#define EW_SILENT 0x20 // don't print "1 returned" from shell -#define EW_EXEC 0x40 // executable files -#define EW_PATH 0x80 // search in 'path' too -#define EW_ICASE 0x100 // ignore case -#define EW_NOERROR 0x200 // no error for bad regexp -#define EW_NOTWILD 0x400 // add match with literal name if exists -#define EW_KEEPDOLLAR 0x800 // do not escape $, $var is expanded +/// Flags for expand_wildcards() +enum { + EW_DIR = 0x01, ///< include directory names + EW_FILE = 0x02, ///< include file names + EW_NOTFOUND = 0x04, ///< include not found names + EW_ADDSLASH = 0x08, ///< append slash to directory name + EW_KEEPALL = 0x10, ///< keep all matches + EW_SILENT = 0x20, ///< don't print "1 returned" from shell + EW_EXEC = 0x40, ///< executable files + EW_PATH = 0x80, ///< search in 'path' too + EW_ICASE = 0x100, ///< ignore case + EW_NOERROR = 0x200, ///< no error for bad regexp + EW_NOTWILD = 0x400, ///< add match with literal name if exists + EW_KEEPDOLLAR = 0x800, ///< do not escape $, $var is expanded + EW_ALLLINKS = 0x1000, ///< also links not pointing to existing file + EW_SHELLCMD = 0x2000, ///< called from expand_shellcmd(), don't check + ///< if executable is in $PATH + EW_DODOT = 0x4000, ///< also files starting with a dot + EW_EMPTYOK = 0x8000, ///< no matches is not an error + EW_NOTENV = 0x10000, ///< do not expand environment variables + EW_NOBREAK = 0x20000, ///< do not invoke breakcheck +}; // Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND // is used when executing commands and EW_SILENT for interactive expanding. -#define EW_ALLLINKS 0x1000 // also links not pointing to existing file -#define EW_SHELLCMD 0x2000 // called from expand_shellcmd(), don't check - // if executable is in $PATH -#define EW_DODOT 0x4000 // also files starting with a dot -#define EW_EMPTYOK 0x8000 // no matches is not an error -#define EW_NOTENV 0x10000 // do not expand environment variables -#define EW_NOBREAK 0x20000 // do not invoke breakcheck /// Return value for the comparison of two files. Also @see path_full_compare. typedef enum file_comparison { diff --git a/src/nvim/shada.c b/src/nvim/shada.c index d288c36f65..819fbcf885 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1117,7 +1117,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) } HistoryMergerState hms[HIST_COUNT]; if (srni_flags & kSDReadHistory) { - for (HistoryType i = 0; i < HIST_COUNT; i++) { + for (int i = 0; i < HIST_COUNT; i++) { hms_init(&hms[i], (uint8_t)i, (size_t)p_hi, true, true); } } @@ -1381,7 +1381,7 @@ shada_read_main_cycle_end: // memory for the history string itself and separator character which // may be assigned right away. if (srni_flags & kSDReadHistory) { - for (HistoryType i = 0; i < HIST_COUNT; i++) { + for (int i = 0; i < HIST_COUNT; i++) { hms_insert_whole_neovim_history(&hms[i]); clr_history(i); int *new_hisidx; @@ -2499,7 +2499,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef bool dump_history = false; // Initialize history merger - for (HistoryType i = 0; i < HIST_COUNT; i++) { + for (int i = 0; i < HIST_COUNT; i++) { int num_saved = get_shada_parameter(hist_type2char(i)); if (num_saved == -1) { num_saved = (int)p_hi; @@ -2893,7 +2893,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef #undef PACK_WMS_ARRAY if (dump_history) { - for (size_t i = 0; i < HIST_COUNT; i++) { + for (int i = 0; i < HIST_COUNT; i++) { if (dump_one_history[i]) { hms_insert_whole_neovim_history(&wms->hms[i]); HMS_ITER(&wms->hms[i], cur_entry, { @@ -2913,7 +2913,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef } shada_write_exit: - for (size_t i = 0; i < HIST_COUNT; i++) { + for (int i = 0; i < HIST_COUNT; i++) { if (dump_one_history[i]) { hms_dealloc(&wms->hms[i]); } diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 7ef10c0acd..4ebd2acc1d 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -705,6 +705,7 @@ static void handle_raw_buffer(TermInput *input, bool force) const size_t bufsize = termkey_get_buffer_size(input->tk); const bool success = termkey_set_buffer_size(input->tk, MAX(bufsize + delta, bufsize * 2)); assert(success); + (void)success; } size_t consumed = termkey_push_bytes(input->tk, ptr, size); @@ -731,6 +732,7 @@ static void handle_raw_buffer(TermInput *input, bool force) // shrink it back down to its original size. const bool success = termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE); assert(success); + (void)success; } } -- cgit From 7feed6ccb7ddfa3bc789158a3b7874d12652e9c5 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:05:33 -0600 Subject: refactor: explicitly abort on OOM condition (#26330) assert() would not abort in release builds, meaning an OOM condition would be undetected. --- src/nvim/tui/input.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 4ebd2acc1d..b9e2d2c9ee 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -700,12 +700,12 @@ static void handle_raw_buffer(TermInput *input, bool force) if (size > termkey_get_buffer_remaining(input->tk)) { // We are processing a very long escape sequence. Increase termkey's // internal buffer size. We don't handle out of memory situations so - // assert the result + // abort if it fails const size_t delta = size - termkey_get_buffer_remaining(input->tk); const size_t bufsize = termkey_get_buffer_size(input->tk); - const bool success = termkey_set_buffer_size(input->tk, MAX(bufsize + delta, bufsize * 2)); - assert(success); - (void)success; + if (!termkey_set_buffer_size(input->tk, MAX(bufsize + delta, bufsize * 2))) { + abort(); + } } size_t consumed = termkey_push_bytes(input->tk, ptr, size); @@ -730,9 +730,9 @@ static void handle_raw_buffer(TermInput *input, bool force) if (tk_count < INPUT_BUFFER_SIZE && tk_size > INPUT_BUFFER_SIZE) { // If the termkey buffer was resized to handle a large input sequence then // shrink it back down to its original size. - const bool success = termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE); - assert(success); - (void)success; + if (!termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE)) { + abort(); + } } } -- cgit From 404043e74c523bff049558685bd88213cc71ed7a Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 1 Nov 2023 22:33:02 +0100 Subject: build: vendor libtermkey This is a proof of concept/WIP to evaluate the viability of vendoring libtermkey as it's been deprecated. --- src/nvim/CMakeLists.txt | 12 +- src/nvim/tui/input.h | 2 +- src/termkey/driver-csi.c | 768 +++++++++++++++++++ src/termkey/driver-ti.c | 633 ++++++++++++++++ src/termkey/termkey-internal.h | 112 +++ src/termkey/termkey.c | 1604 ++++++++++++++++++++++++++++++++++++++++ src/termkey/termkey.h | 249 +++++++ 7 files changed, 3373 insertions(+), 7 deletions(-) create mode 100644 src/termkey/driver-csi.c create mode 100644 src/termkey/driver-ti.c create mode 100644 src/termkey/termkey-internal.h create mode 100644 src/termkey/termkey.c create mode 100644 src/termkey/termkey.h (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index a8ce9edff8..6a01632040 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -37,7 +37,6 @@ target_link_libraries(main_lib INTERFACE ${LUV_LIBRARY}) find_package(Iconv REQUIRED) find_package(Lpeg REQUIRED) -find_package(Libtermkey 0.22 REQUIRED) find_package(Libvterm 0.3.3 REQUIRED) find_package(Msgpack 1.0.0 REQUIRED) find_package(Treesitter 0.20.8 REQUIRED) @@ -45,7 +44,6 @@ find_package(Unibilium 2.0 REQUIRED) target_link_libraries(main_lib INTERFACE iconv - libtermkey libvterm msgpack treesitter @@ -60,6 +58,8 @@ if (LIBINTL_LIBRARY) target_link_libraries(main_lib INTERFACE ${LIBINTL_LIBRARY}) endif() +target_compile_definitions(main_lib INTERFACE HAVE_UNIBILIUM) + # The unit test lib requires LuaJIT; it will be skipped if LuaJIT is missing. option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF) if(PREFER_LUA) @@ -376,8 +376,8 @@ file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}) glob_wrapper(NVIM_SOURCES *.c) glob_wrapper(NVIM_HEADERS *.h) -glob_wrapper(EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c ../klib/*.c) -glob_wrapper(EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h ../klib/*.h) +glob_wrapper(EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c ../klib/*.c ../termkey/*.c) +glob_wrapper(EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h ../klib/*.h ../termkey/*.h) glob_wrapper(NLUA0_SOURCES ../mpack/*.c) @@ -436,13 +436,13 @@ endforeach() list(REMOVE_ITEM NVIM_SOURCES ${to_remove}) -# xdiff, mpack, lua-cjson: inlined external project, we don't maintain it. #9306 +# xdiff, mpack, lua-cjson, termkey: inlined external project, we don't maintain it. #9306 if(MSVC) set_source_files_properties( ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -wd4090 -wd4244 -wd4267") else() set_source_files_properties( - ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion -Wno-missing-noreturn -Wno-missing-format-attribute -Wno-double-promotion -Wno-strict-prototypes -Wno-misleading-indentation") + ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion -Wno-missing-noreturn -Wno-missing-format-attribute -Wno-double-promotion -Wno-strict-prototypes -Wno-misleading-indentation -Wno-sign-compare -Wno-implicit-fallthrough -Wno-missing-prototypes -Wno-missing-field-initializers") endif() # Log level (NVIM_LOG_DEBUG in log.h) diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index 2743a5e286..27a0291f5b 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -2,7 +2,6 @@ #include #include -#include #include #include "nvim/event/loop.h" @@ -12,6 +11,7 @@ #include "nvim/tui/input_defs.h" // IWYU pragma: export #include "nvim/tui/tui.h" #include "nvim/types_defs.h" +#include "termkey/termkey.h" typedef enum { kKeyEncodingLegacy, ///< Legacy key encoding diff --git a/src/termkey/driver-csi.c b/src/termkey/driver-csi.c new file mode 100644 index 0000000000..37b14986d0 --- /dev/null +++ b/src/termkey/driver-csi.c @@ -0,0 +1,768 @@ +#include "termkey.h" +#include "termkey-internal.h" + +#include +#include + +// There are 64 codes 0x40 - 0x7F +static int keyinfo_initialised = 0; +static struct keyinfo ss3s[64]; +static char ss3_kpalts[64]; + +typedef struct { + TermKey *tk; + int saved_string_id; + char *saved_string; +} TermKeyCsi; + +typedef TermKeyResult CsiHandler(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args); +static CsiHandler *csi_handlers[64]; + +/* + * Handler for CSI/SS3 cmd keys + */ + +static struct keyinfo csi_ss3s[64]; + +static TermKeyResult handle_csi_ss3_full(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args) +{ + if(args > 1 && arg[1] != -1) + key->modifiers = arg[1] - 1; + else + key->modifiers = 0; + + key->type = csi_ss3s[cmd - 0x40].type; + key->code.sym = csi_ss3s[cmd - 0x40].sym; + key->modifiers &= ~(csi_ss3s[cmd - 0x40].modifier_mask); + key->modifiers |= csi_ss3s[cmd - 0x40].modifier_set; + + if(key->code.sym == TERMKEY_SYM_UNKNOWN) + return TERMKEY_RES_NONE; + + return TERMKEY_RES_KEY; +} + +static void register_csi_ss3_full(TermKeyType type, TermKeySym sym, int modifier_set, int modifier_mask, unsigned char cmd) +{ + if(cmd < 0x40 || cmd >= 0x80) { + return; + } + + csi_ss3s[cmd - 0x40].type = type; + csi_ss3s[cmd - 0x40].sym = sym; + csi_ss3s[cmd - 0x40].modifier_set = modifier_set; + csi_ss3s[cmd - 0x40].modifier_mask = modifier_mask; + + csi_handlers[cmd - 0x40] = &handle_csi_ss3_full; +} + +static void register_csi_ss3(TermKeyType type, TermKeySym sym, unsigned char cmd) +{ + register_csi_ss3_full(type, sym, 0, 0, cmd); +} + +/* + * Handler for SS3 keys with kpad alternate representations + */ + +static void register_ss3kpalt(TermKeyType type, TermKeySym sym, unsigned char cmd, char kpalt) +{ + if(cmd < 0x40 || cmd >= 0x80) { + return; + } + + ss3s[cmd - 0x40].type = type; + ss3s[cmd - 0x40].sym = sym; + ss3s[cmd - 0x40].modifier_set = 0; + ss3s[cmd - 0x40].modifier_mask = 0; + ss3_kpalts[cmd - 0x40] = kpalt; +} + +/* + * Handler for CSI number ~ function keys + */ + +static struct keyinfo csifuncs[35]; /* This value must be increased if more CSI function keys are added */ +#define NCSIFUNCS (sizeof(csifuncs)/sizeof(csifuncs[0])) + +static TermKeyResult handle_csifunc(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args) +{ + if(args > 1 && arg[1] != -1) + key->modifiers = arg[1] - 1; + else + key->modifiers = 0; + + key->type = TERMKEY_TYPE_KEYSYM; + + if(arg[0] == 27) { + int mod = key->modifiers; + (*tk->method.emit_codepoint)(tk, arg[2], key); + key->modifiers |= mod; + } + else if(arg[0] >= 0 && arg[0] < NCSIFUNCS) { + key->type = csifuncs[arg[0]].type; + key->code.sym = csifuncs[arg[0]].sym; + key->modifiers &= ~(csifuncs[arg[0]].modifier_mask); + key->modifiers |= csifuncs[arg[0]].modifier_set; + } + else + key->code.sym = TERMKEY_SYM_UNKNOWN; + + if(key->code.sym == TERMKEY_SYM_UNKNOWN) { +#ifdef DEBUG + fprintf(stderr, "CSI: Unknown function key %ld\n", arg[0]); +#endif + return TERMKEY_RES_NONE; + } + + return TERMKEY_RES_KEY; +} + +static void register_csifunc(TermKeyType type, TermKeySym sym, int number) +{ + if(number >= NCSIFUNCS) { + return; + } + + csifuncs[number].type = type; + csifuncs[number].sym = sym; + csifuncs[number].modifier_set = 0; + csifuncs[number].modifier_mask = 0; + + csi_handlers['~' - 0x40] = &handle_csifunc; +} + +/* + * Handler for CSI u extended Unicode keys + */ + +static TermKeyResult handle_csi_u(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args) +{ + switch(cmd) { + case 'u': { + if(args > 1 && arg[1] != -1) + key->modifiers = arg[1] - 1; + else + key->modifiers = 0; + + int mod = key->modifiers; + key->type = TERMKEY_TYPE_KEYSYM; + (*tk->method.emit_codepoint)(tk, arg[0], key); + key->modifiers |= mod; + + return TERMKEY_RES_KEY; + } + default: + return TERMKEY_RES_NONE; + } +} + +/* + * Handler for CSI M / CSI m mouse events in SGR and rxvt encodings + * Note: This does not handle X10 encoding + */ + +static TermKeyResult handle_csi_m(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args) +{ + int initial = cmd >> 8; + cmd &= 0xff; + + switch(cmd) { + case 'M': + case 'm': + break; + default: + return TERMKEY_RES_NONE; + } + + if(!initial && args >= 3) { // rxvt protocol + key->type = TERMKEY_TYPE_MOUSE; + key->code.mouse[0] = arg[0]; + + key->modifiers = (key->code.mouse[0] & 0x1c) >> 2; + key->code.mouse[0] &= ~0x1c; + + termkey_key_set_linecol(key, arg[1], arg[2]); + + return TERMKEY_RES_KEY; + } + + if(initial == '<' && args >= 3) { // SGR protocol + key->type = TERMKEY_TYPE_MOUSE; + key->code.mouse[0] = arg[0]; + + key->modifiers = (key->code.mouse[0] & 0x1c) >> 2; + key->code.mouse[0] &= ~0x1c; + + termkey_key_set_linecol(key, arg[1], arg[2]); + + if(cmd == 'm') // release + key->code.mouse[3] |= 0x80; + + return TERMKEY_RES_KEY; + } + + return TERMKEY_RES_NONE; +} + +TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col) +{ + if(key->type != TERMKEY_TYPE_MOUSE) + return TERMKEY_RES_NONE; + + if(button) + *button = 0; + + termkey_key_get_linecol(key, line, col); + + if(!event) + return TERMKEY_RES_KEY; + + int btn = 0; + + int code = key->code.mouse[0]; + + int drag = code & 0x20; + + code &= ~0x3c; + + switch(code) { + case 0: + case 1: + case 2: + *event = drag ? TERMKEY_MOUSE_DRAG : TERMKEY_MOUSE_PRESS; + btn = code + 1; + break; + + case 3: + *event = TERMKEY_MOUSE_RELEASE; + // no button hint + break; + + case 64: + case 65: + *event = drag ? TERMKEY_MOUSE_DRAG : TERMKEY_MOUSE_PRESS; + btn = code + 4 - 64; + break; + + default: + *event = TERMKEY_MOUSE_UNKNOWN; + } + + if(button) + *button = btn; + + if(key->code.mouse[3] & 0x80) + *event = TERMKEY_MOUSE_RELEASE; + + return TERMKEY_RES_KEY; +} + +/* + * Handler for CSI ? R position reports + * A plain CSI R with no arguments is probably actually + */ + +static TermKeyResult handle_csi_R(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args) +{ + switch(cmd) { + case 'R'|'?'<<8: + if(args < 2) + return TERMKEY_RES_NONE; + + key->type = TERMKEY_TYPE_POSITION; + termkey_key_set_linecol(key, arg[1], arg[0]); + return TERMKEY_RES_KEY; + + default: + return handle_csi_ss3_full(tk, key, cmd, arg, args); + } +} + +TermKeyResult termkey_interpret_position(TermKey *tk, const TermKeyKey *key, int *line, int *col) +{ + if(key->type != TERMKEY_TYPE_POSITION) + return TERMKEY_RES_NONE; + + termkey_key_get_linecol(key, line, col); + + return TERMKEY_RES_KEY; +} + +/* + * Handler for CSI $y mode status reports + */ + +static TermKeyResult handle_csi_y(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args) +{ + switch(cmd) { + case 'y'|'$'<<16: + case 'y'|'$'<<16 | '?'<<8: + if(args < 2) + return TERMKEY_RES_NONE; + + key->type = TERMKEY_TYPE_MODEREPORT; + key->code.mouse[0] = (cmd >> 8); + key->code.mouse[1] = arg[0] >> 8; + key->code.mouse[2] = arg[0] & 0xff; + key->code.mouse[3] = arg[1]; + return TERMKEY_RES_KEY; + + default: + return TERMKEY_RES_NONE; + } +} + +TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, int *initial, int *mode, int *value) +{ + if(key->type != TERMKEY_TYPE_MODEREPORT) + return TERMKEY_RES_NONE; + + if(initial) + *initial = key->code.mouse[0]; + + if(mode) + *mode = (key->code.mouse[1] << 8) | key->code.mouse[2]; + + if(value) + *value = key->code.mouse[3]; + + return TERMKEY_RES_KEY; +} + +#define CHARAT(i) (tk->buffer[tk->buffstart + (i)]) + +static TermKeyResult parse_csi(TermKey *tk, size_t introlen, size_t *csi_len, long args[], size_t *nargs, unsigned long *commandp) +{ + size_t csi_end = introlen; + + while(csi_end < tk->buffcount) { + if(CHARAT(csi_end) >= 0x40 && CHARAT(csi_end) < 0x80) + break; + csi_end++; + } + + if(csi_end >= tk->buffcount) + return TERMKEY_RES_AGAIN; + + unsigned char cmd = CHARAT(csi_end); + *commandp = cmd; + + char present = 0; + int argi = 0; + + size_t p = introlen; + + // See if there is an initial byte + if(CHARAT(p) >= '<' && CHARAT(p) <= '?') { + *commandp |= (CHARAT(p) << 8); + p++; + } + + // Now attempt to parse out up number;number;... separated values + while(p < csi_end) { + unsigned char c = CHARAT(p); + + if(c >= '0' && c <= '9') { + if(!present) { + args[argi] = c - '0'; + present = 1; + } + else { + args[argi] = (args[argi] * 10) + c - '0'; + } + } + else if(c == ';') { + if(!present) + args[argi] = -1; + present = 0; + argi++; + + if(argi > 16) + break; + } + else if(c >= 0x20 && c <= 0x2f) { + *commandp |= c << 16; + break; + } + + p++; + } + + if(present) + argi++; + + *nargs = argi; + *csi_len = csi_end + 1; + + return TERMKEY_RES_KEY; +} + +TermKeyResult termkey_interpret_csi(TermKey *tk, const TermKeyKey *key, long args[], size_t *nargs, unsigned long *cmd) +{ + size_t dummy; + + if(tk->hightide == 0) + return TERMKEY_RES_NONE; + if(key->type != TERMKEY_TYPE_UNKNOWN_CSI) + return TERMKEY_RES_NONE; + + return parse_csi(tk, 0, &dummy, args, nargs, cmd); +} + +static int register_keys(void) +{ + int i; + + for(i = 0; i < 64; i++) { + csi_ss3s[i].sym = TERMKEY_SYM_UNKNOWN; + ss3s[i].sym = TERMKEY_SYM_UNKNOWN; + ss3_kpalts[i] = 0; + } + + for(i = 0; i < NCSIFUNCS; i++) + csifuncs[i].sym = TERMKEY_SYM_UNKNOWN; + + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UP, 'A'); + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DOWN, 'B'); + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RIGHT, 'C'); + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_LEFT, 'D'); + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 'E'); + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_END, 'F'); + register_csi_ss3(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HOME, 'H'); + register_csi_ss3(TERMKEY_TYPE_FUNCTION, 1, 'P'); + register_csi_ss3(TERMKEY_TYPE_FUNCTION, 2, 'Q'); + register_csi_ss3(TERMKEY_TYPE_FUNCTION, 3, 'R'); + register_csi_ss3(TERMKEY_TYPE_FUNCTION, 4, 'S'); + + register_csi_ss3_full(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_TAB, TERMKEY_KEYMOD_SHIFT, TERMKEY_KEYMOD_SHIFT, 'Z'); + + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPENTER, 'M', 0); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPEQUALS, 'X', '='); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPMULT, 'j', '*'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPPLUS, 'k', '+'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPCOMMA, 'l', ','); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPMINUS, 'm', '-'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPPERIOD, 'n', '.'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KPDIV, 'o', '/'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP0, 'p', '0'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP1, 'q', '1'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP2, 'r', '2'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP3, 's', '3'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP4, 't', '4'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP5, 'u', '5'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP6, 'v', '6'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP7, 'w', '7'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP8, 'x', '8'); + register_ss3kpalt(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_KP9, 'y', '9'); + + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_FIND, 1); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_INSERT, 2); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DELETE, 3); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SELECT, 4); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 5); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 6); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HOME, 7); + register_csifunc(TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_END, 8); + + register_csifunc(TERMKEY_TYPE_FUNCTION, 1, 11); + register_csifunc(TERMKEY_TYPE_FUNCTION, 2, 12); + register_csifunc(TERMKEY_TYPE_FUNCTION, 3, 13); + register_csifunc(TERMKEY_TYPE_FUNCTION, 4, 14); + register_csifunc(TERMKEY_TYPE_FUNCTION, 5, 15); + register_csifunc(TERMKEY_TYPE_FUNCTION, 6, 17); + register_csifunc(TERMKEY_TYPE_FUNCTION, 7, 18); + register_csifunc(TERMKEY_TYPE_FUNCTION, 8, 19); + register_csifunc(TERMKEY_TYPE_FUNCTION, 9, 20); + register_csifunc(TERMKEY_TYPE_FUNCTION, 10, 21); + register_csifunc(TERMKEY_TYPE_FUNCTION, 11, 23); + register_csifunc(TERMKEY_TYPE_FUNCTION, 12, 24); + register_csifunc(TERMKEY_TYPE_FUNCTION, 13, 25); + register_csifunc(TERMKEY_TYPE_FUNCTION, 14, 26); + register_csifunc(TERMKEY_TYPE_FUNCTION, 15, 28); + register_csifunc(TERMKEY_TYPE_FUNCTION, 16, 29); + register_csifunc(TERMKEY_TYPE_FUNCTION, 17, 31); + register_csifunc(TERMKEY_TYPE_FUNCTION, 18, 32); + register_csifunc(TERMKEY_TYPE_FUNCTION, 19, 33); + register_csifunc(TERMKEY_TYPE_FUNCTION, 20, 34); + + csi_handlers['u' - 0x40] = &handle_csi_u; + + csi_handlers['M' - 0x40] = &handle_csi_m; + csi_handlers['m' - 0x40] = &handle_csi_m; + + csi_handlers['R' - 0x40] = &handle_csi_R; + + csi_handlers['y' - 0x40] = &handle_csi_y; + + keyinfo_initialised = 1; + return 1; +} + +static void *new_driver(TermKey *tk, const char *term) +{ + if(!keyinfo_initialised) + if(!register_keys()) + return NULL; + + TermKeyCsi *csi = malloc(sizeof *csi); + if(!csi) + return NULL; + + csi->tk = tk; + csi->saved_string_id = 0; + csi->saved_string = NULL; + + return csi; +} + +static void free_driver(void *info) +{ + TermKeyCsi *csi = info; + + if(csi->saved_string) + free(csi->saved_string); + + free(csi); +} + +static TermKeyResult peekkey_csi(TermKey *tk, TermKeyCsi *csi, size_t introlen, TermKeyKey *key, int force, size_t *nbytep) +{ + size_t csi_len; + size_t args = 16; + long arg[16]; + unsigned long cmd; + + TermKeyResult ret = parse_csi(tk, introlen, &csi_len, arg, &args, &cmd); + + if(ret == TERMKEY_RES_AGAIN) { + if(!force) + return TERMKEY_RES_AGAIN; + + (*tk->method.emit_codepoint)(tk, '[', key); + key->modifiers |= TERMKEY_KEYMOD_ALT; + *nbytep = introlen; + return TERMKEY_RES_KEY; + } + + if(cmd == 'M' && args < 3) { // Mouse in X10 encoding consumes the next 3 bytes also + tk->buffstart += csi_len; + tk->buffcount -= csi_len; + + TermKeyResult mouse_result = (*tk->method.peekkey_mouse)(tk, key, nbytep); + + tk->buffstart -= csi_len; + tk->buffcount += csi_len; + + if(mouse_result == TERMKEY_RES_KEY) + *nbytep += csi_len; + + return mouse_result; + } + + TermKeyResult result = TERMKEY_RES_NONE; + + // We know from the logic above that cmd must be >= 0x40 and < 0x80 + if(csi_handlers[(cmd & 0xff) - 0x40]) + result = (*csi_handlers[(cmd & 0xff) - 0x40])(tk, key, cmd, arg, args); + + if(result == TERMKEY_RES_NONE) { +#ifdef DEBUG + switch(args) { + case 0: + fprintf(stderr, "CSI: Unknown cmd=%c\n", (char)cmd); + break; + case 1: + fprintf(stderr, "CSI: Unknown arg1=%ld cmd=%c\n", arg[0], (char)cmd); + break; + case 2: + fprintf(stderr, "CSI: Unknown arg1=%ld arg2=%ld cmd=%c\n", arg[0], arg[1], (char)cmd); + break; + case 3: + fprintf(stderr, "CSI: Unknown arg1=%ld arg2=%ld arg3=%ld cmd=%c\n", arg[0], arg[1], arg[2], (char)cmd); + break; + default: + fprintf(stderr, "CSI: Unknown arg1=%ld arg2=%ld arg3=%ld ... args=%d cmd=%c\n", arg[0], arg[1], arg[2], args, (char)cmd); + break; + } +#endif + key->type = TERMKEY_TYPE_UNKNOWN_CSI; + key->code.number = cmd; + key->modifiers = 0; + + tk->hightide = csi_len - introlen; + *nbytep = introlen; // Do not yet eat the data bytes + return TERMKEY_RES_KEY; + } + + *nbytep = csi_len; + return result; +} + +static TermKeyResult peekkey_ss3(TermKey *tk, TermKeyCsi *csi, size_t introlen, TermKeyKey *key, int force, size_t *nbytep) +{ + if(tk->buffcount < introlen + 1) { + if(!force) + return TERMKEY_RES_AGAIN; + + (*tk->method.emit_codepoint)(tk, 'O', key); + key->modifiers |= TERMKEY_KEYMOD_ALT; + *nbytep = tk->buffcount; + return TERMKEY_RES_KEY; + } + + unsigned char cmd = CHARAT(introlen); + + if(cmd < 0x40 || cmd >= 0x80) + return TERMKEY_RES_NONE; + + key->type = csi_ss3s[cmd - 0x40].type; + key->code.sym = csi_ss3s[cmd - 0x40].sym; + key->modifiers = csi_ss3s[cmd - 0x40].modifier_set; + + if(key->code.sym == TERMKEY_SYM_UNKNOWN) { + if(tk->flags & TERMKEY_FLAG_CONVERTKP && ss3_kpalts[cmd - 0x40]) { + key->type = TERMKEY_TYPE_UNICODE; + key->code.codepoint = ss3_kpalts[cmd - 0x40]; + key->modifiers = 0; + + key->utf8[0] = key->code.codepoint; + key->utf8[1] = 0; + } + else { + key->type = ss3s[cmd - 0x40].type; + key->code.sym = ss3s[cmd - 0x40].sym; + key->modifiers = ss3s[cmd - 0x40].modifier_set; + } + } + + if(key->code.sym == TERMKEY_SYM_UNKNOWN) { +#ifdef DEBUG + fprintf(stderr, "CSI: Unknown SS3 %c (0x%02x)\n", (char)cmd, cmd); +#endif + return TERMKEY_RES_NONE; + } + + *nbytep = introlen + 1; + + return TERMKEY_RES_KEY; +} + +static TermKeyResult peekkey_ctrlstring(TermKey *tk, TermKeyCsi *csi, size_t introlen, TermKeyKey *key, int force, size_t *nbytep) +{ + size_t str_end = introlen; + + while(str_end < tk->buffcount) { + if(CHARAT(str_end) == 0x9c) // ST + break; + if(CHARAT(str_end) == 0x1b && + (str_end + 1) < tk->buffcount && + CHARAT(str_end+1) == 0x5c) // ESC-prefixed ST + break; + + str_end++; + } + + if(str_end >= tk->buffcount) + return TERMKEY_RES_AGAIN; + +#ifdef DEBUG + fprintf(stderr, "Found a control string: %*s", + str_end - introlen, tk->buffer + tk->buffstart + introlen); +#endif + + *nbytep = str_end + 1; + if(CHARAT(str_end) == 0x1b) + (*nbytep)++; + + if(csi->saved_string) + free(csi->saved_string); + + size_t len = str_end - introlen; + + csi->saved_string_id++; + csi->saved_string = malloc(len + 1); + + strncpy(csi->saved_string, (char *)tk->buffer + tk->buffstart + introlen, len); + csi->saved_string[len] = 0; + + key->type = (CHARAT(introlen-1) & 0x1f) == 0x10 ? + TERMKEY_TYPE_DCS : TERMKEY_TYPE_OSC; + key->code.number = csi->saved_string_id; + key->modifiers = 0; + + return TERMKEY_RES_KEY; +} + +static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep) +{ + if(tk->buffcount == 0) + return tk->is_closed ? TERMKEY_RES_EOF : TERMKEY_RES_NONE; + + TermKeyCsi *csi = info; + + switch(CHARAT(0)) { + case 0x1b: + if(tk->buffcount < 2) + return TERMKEY_RES_NONE; + + switch(CHARAT(1)) { + case 0x4f: // ESC-prefixed SS3 + return peekkey_ss3(tk, csi, 2, key, force, nbytep); + + case 0x50: // ESC-prefixed DCS + case 0x5d: // ESC-prefixed OSC + return peekkey_ctrlstring(tk, csi, 2, key, force, nbytep); + + case 0x5b: // ESC-prefixed CSI + return peekkey_csi(tk, csi, 2, key, force, nbytep); + } + + return TERMKEY_RES_NONE; + + case 0x8f: // SS3 + return peekkey_ss3(tk, csi, 1, key, force, nbytep); + + case 0x90: // DCS + case 0x9d: // OSC + return peekkey_ctrlstring(tk, csi, 1, key, force, nbytep); + + case 0x9b: // CSI + return peekkey_csi(tk, csi, 1, key, force, nbytep); + } + + return TERMKEY_RES_NONE; +} + +struct TermKeyDriver termkey_driver_csi = { + .name = "CSI", + + .new_driver = new_driver, + .free_driver = free_driver, + + .peekkey = peekkey, +}; + +TermKeyResult termkey_interpret_string(TermKey *tk, const TermKeyKey *key, const char **strp) +{ + struct TermKeyDriverNode *p; + for(p = tk->drivers; p; p = p->next) + if(p->driver == &termkey_driver_csi) + break; + + if(!p) + return TERMKEY_RES_NONE; + + if(key->type != TERMKEY_TYPE_DCS && + key->type != TERMKEY_TYPE_OSC) + return TERMKEY_RES_NONE; + + TermKeyCsi *csi = p->info; + + if(csi->saved_string_id != key->code.number) + return TERMKEY_RES_NONE; + + *strp = csi->saved_string; + + return TERMKEY_RES_KEY; +} diff --git a/src/termkey/driver-ti.c b/src/termkey/driver-ti.c new file mode 100644 index 0000000000..69bc3684d3 --- /dev/null +++ b/src/termkey/driver-ti.c @@ -0,0 +1,633 @@ +// we want strdup() +#define _XOPEN_SOURCE 600 + +#include "termkey.h" +#include "termkey-internal.h" + +#ifdef HAVE_UNIBILIUM +# include +#else +# include +# include + +/* curses.h has just polluted our namespace. We want this back */ +# undef buttons +#endif + +#include +#include +#include +#include +#include +#ifndef _WIN32 +# include +#endif +#include +#include + +#define streq(a,b) (!strcmp(a,b)) + +#define MAX_FUNCNAME 9 + +static struct { + const char *funcname; + TermKeyType type; + TermKeySym sym; + int mods; +} funcs[] = +{ + /* THIS LIST MUST REMAIN SORTED! */ + { "backspace", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BACKSPACE, 0 }, + { "begin", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 0 }, + { "beg", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 0 }, + { "btab", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_TAB, TERMKEY_KEYMOD_SHIFT }, + { "cancel", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CANCEL, 0 }, + { "clear", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CLEAR, 0 }, + { "close", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CLOSE, 0 }, + { "command", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_COMMAND, 0 }, + { "copy", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_COPY, 0 }, + { "dc", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DELETE, 0 }, + { "down", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DOWN, 0 }, + { "end", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_END, 0 }, + { "enter", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_ENTER, 0 }, + { "exit", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_EXIT, 0 }, + { "find", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_FIND, 0 }, + { "help", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HELP, 0 }, + { "home", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HOME, 0 }, + { "ic", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_INSERT, 0 }, + { "left", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_LEFT, 0 }, + { "mark", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MARK, 0 }, + { "message", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MESSAGE, 0 }, + { "move", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MOVE, 0 }, + { "next", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 0 }, // Not quite, but it's the best we can do + { "npage", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 0 }, + { "open", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_OPEN, 0 }, + { "options", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_OPTIONS, 0 }, + { "ppage", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 0 }, + { "previous", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 0 }, // Not quite, but it's the best we can do + { "print", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PRINT, 0 }, + { "redo", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REDO, 0 }, + { "reference", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REFERENCE, 0 }, + { "refresh", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REFRESH, 0 }, + { "replace", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REPLACE, 0 }, + { "restart", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RESTART, 0 }, + { "resume", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RESUME, 0 }, + { "right", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RIGHT, 0 }, + { "save", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SAVE, 0 }, + { "select", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SELECT, 0 }, + { "suspend", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SUSPEND, 0 }, + { "undo", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UNDO, 0 }, + { "up", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UP, 0 }, + { NULL }, +}; + +#ifdef HAVE_UNIBILIUM +static enum unibi_string unibi_lookup_str(const char *name) +{ + for(enum unibi_string ret = unibi_string_begin_+1; ret < unibi_string_end_; ret++) + if(streq(unibi_name_str(ret), name)) + return ret; + + return -1; +} + +static const char *unibi_get_str_by_name(const unibi_term *ut, const char *name) +{ + enum unibi_string idx = unibi_lookup_str(name); + if(idx == (enum unibi_string)-1) + return NULL; + + return unibi_get_str(ut, idx); +} +#endif + +/* To be efficient at lookups, we store the byte sequence => keyinfo mapping + * in a trie. This avoids a slow linear search through a flat list of + * sequences. Because it is likely most nodes will be very sparse, we optimise + * vector to store an extent map after the database is loaded. + */ + +typedef enum { + TYPE_KEY, + TYPE_ARR, +} trie_nodetype; + +struct trie_node { + trie_nodetype type; +}; + +struct trie_node_key { + trie_nodetype type; + struct keyinfo key; +}; + +struct trie_node_arr { + trie_nodetype type; + unsigned char min, max; /* INCLUSIVE endpoints of the extent range */ + struct trie_node *arr[]; /* dynamic size at allocation time */ +}; + +typedef struct { + TermKey *tk; + +#ifdef HAVE_UNIBILIUM + unibi_term *unibi; /* only valid until first 'start' call */ +#else + char *term; /* only valid until first 'start' call */ +#endif + + struct trie_node *root; + + char *start_string; + char *stop_string; +} TermKeyTI; + +static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node); + +static struct trie_node *new_node_key(TermKeyType type, TermKeySym sym, int modmask, int modset) +{ + struct trie_node_key *n = malloc(sizeof(*n)); + if(!n) + return NULL; + + n->type = TYPE_KEY; + + n->key.type = type; + n->key.sym = sym; + n->key.modifier_mask = modmask; + n->key.modifier_set = modset; + + return (struct trie_node*)n; +} + +static struct trie_node *new_node_arr(unsigned char min, unsigned char max) +{ + struct trie_node_arr *n = malloc(sizeof(*n) + ((int)max-min+1) * sizeof(n->arr[0])); + if(!n) + return NULL; + + n->type = TYPE_ARR; + n->min = min; n->max = max; + + int i; + for(i = min; i <= max; i++) + n->arr[i-min] = NULL; + + return (struct trie_node*)n; +} + +static struct trie_node *lookup_next(struct trie_node *n, unsigned char b) +{ + switch(n->type) { + case TYPE_KEY: + fprintf(stderr, "ABORT: lookup_next within a TYPE_KEY node\n"); + abort(); + case TYPE_ARR: + { + struct trie_node_arr *nar = (struct trie_node_arr*)n; + if(b < nar->min || b > nar->max) + return NULL; + return nar->arr[b - nar->min]; + } + } + + return NULL; // Never reached but keeps compiler happy +} + +static void free_trie(struct trie_node *n) +{ + switch(n->type) { + case TYPE_KEY: + break; + case TYPE_ARR: + { + struct trie_node_arr *nar = (struct trie_node_arr*)n; + int i; + for(i = nar->min; i <= nar->max; i++) + if(nar->arr[i - nar->min]) + free_trie(nar->arr[i - nar->min]); + break; + } + } + + free(n); +} + +static struct trie_node *compress_trie(struct trie_node *n) +{ + if(!n) + return NULL; + + switch(n->type) { + case TYPE_KEY: + return n; + case TYPE_ARR: + { + struct trie_node_arr *nar = (struct trie_node_arr*)n; + unsigned char min, max; + // Find the real bounds + for(min = 0; !nar->arr[min]; min++) + if(min == 255 && !nar->arr[min]) { + free(nar); + return new_node_arr(1, 0); + } + + for(max = 0xff; !nar->arr[max]; max--) + ; + + struct trie_node_arr *new = (struct trie_node_arr*)new_node_arr(min, max); + int i; + for(i = min; i <= max; i++) + new->arr[i - min] = compress_trie(nar->arr[i]); + + free(nar); + return (struct trie_node*)new; + } + } + + return n; +} + +static bool try_load_terminfo_key(TermKeyTI *ti, const char *name, struct keyinfo *info) +{ + const char *value = NULL; + +#ifdef HAVE_UNIBILIUM + if(ti->unibi) + value = unibi_get_str_by_name(ti->unibi, name); +#else + if(ti->term) + value = tigetstr(name); +#endif + + if(ti->tk->ti_getstr_hook) + value = (ti->tk->ti_getstr_hook)(name, value, ti->tk->ti_getstr_hook_data); + + if(!value || value == (char*)-1 || !value[0]) + return false; + + struct trie_node *node = new_node_key(info->type, info->sym, info->modifier_mask, info->modifier_set); + insert_seq(ti, value, node); + + return true; +} + +static int load_terminfo(TermKeyTI *ti) +{ + int i; + +#ifdef HAVE_UNIBILIUM + unibi_term *unibi = ti->unibi; +#else + { + int err; + + /* Have to cast away the const. But it's OK - we know terminfo won't really + * modify term */ + if(setupterm((char*)ti->term, 1, &err) != OK) + return 0; + } +#endif + + ti->root = new_node_arr(0, 0xff); + if(!ti->root) + return 0; + + /* First the regular key strings + */ + for(i = 0; funcs[i].funcname; i++) { + char name[MAX_FUNCNAME + 5 + 1]; + + sprintf(name, "key_%s", funcs[i].funcname); + if(!try_load_terminfo_key(ti, name, &(struct keyinfo){ + .type = funcs[i].type, + .sym = funcs[i].sym, + .modifier_mask = funcs[i].mods, + .modifier_set = funcs[i].mods, + })) + continue; + + /* Maybe it has a shifted version */ + sprintf(name, "key_s%s", funcs[i].funcname); + try_load_terminfo_key(ti, name, &(struct keyinfo){ + .type = funcs[i].type, + .sym = funcs[i].sym, + .modifier_mask = funcs[i].mods | TERMKEY_KEYMOD_SHIFT, + .modifier_set = funcs[i].mods | TERMKEY_KEYMOD_SHIFT, + }); + } + + /* Now the F keys + */ + for(i = 1; i < 255; i++) { + char name[9]; + sprintf(name, "key_f%d", i); + if(!try_load_terminfo_key(ti, name, &(struct keyinfo){ + .type = TERMKEY_TYPE_FUNCTION, + .sym = i, + .modifier_mask = 0, + .modifier_set = 0, + })) + break; + } + + /* Finally mouse mode */ + try_load_terminfo_key(ti, "key_mouse", &(struct keyinfo){ + .type = TERMKEY_TYPE_MOUSE, + }); + + /* Take copies of these terminfo strings, in case we build multiple termkey + * instances for multiple different termtypes, and it's different by the + * time we want to use it + */ +#ifdef HAVE_UNIBILIUM + const char *keypad_xmit = unibi ? + unibi_get_str(unibi, unibi_keypad_xmit) : + NULL; +#endif + + if(keypad_xmit) + ti->start_string = strdup(keypad_xmit); + else + ti->start_string = NULL; + +#ifdef HAVE_UNIBILIUM + const char *keypad_local = unibi ? + unibi_get_str(unibi, unibi_keypad_local) : + NULL; +#endif + + if(keypad_local) + ti->stop_string = strdup(keypad_local); + else + ti->stop_string = NULL; + +#ifdef HAVE_UNIBILIUM + if(unibi) + unibi_destroy(unibi); + + ti->unibi = NULL; +#else + if(ti->term) + free(ti->term); + + ti->term = NULL; +#endif + + ti->root = compress_trie(ti->root); + + return 1; +} + +static void *new_driver(TermKey *tk, const char *term) +{ + TermKeyTI *ti = malloc(sizeof *ti); + if(!ti) + return NULL; + + ti->tk = tk; + ti->root = NULL; + ti->start_string = NULL; + ti->stop_string = NULL; + +#ifdef HAVE_UNIBILIUM + ti->unibi = unibi_from_term(term); + int saved_errno = errno; + if(!ti->unibi && saved_errno != ENOENT) { + free(ti); + return NULL; + } + /* ti->unibi may be NULL if errno == ENOENT. That means the terminal wasn't + * known. Lets keep going because if we get getstr hook that might invent + * new strings for us + */ +#else + { + int err; + + ti->term = NULL; + + /* Have to cast away the const. But it's OK - we know terminfo won't really + * modify term */ + if(setupterm((char*)term, 1, &err) == OK) + ti->term = strdup(term); + } +#endif + + return ti; +} + +static int start_driver(TermKey *tk, void *info) +{ + TermKeyTI *ti = info; + struct stat statbuf; + char *start_string; + size_t len; + + if(!ti->root) + load_terminfo(ti); + + start_string = ti->start_string; + + if(tk->fd == -1 || !start_string) + return 1; + + /* The terminfo database will contain keys in application cursor key mode. + * We may need to enable that mode + */ + + /* There's no point trying to write() to a pipe */ + if(fstat(tk->fd, &statbuf) == -1) + return 0; + +#ifndef _WIN32 + if(S_ISFIFO(statbuf.st_mode)) + return 1; +#endif + + // Can't call putp or tputs because they suck and don't give us fd control + len = strlen(start_string); + while(len) { + size_t written = write(tk->fd, start_string, len); + if(written == -1) + return 0; + start_string += written; + len -= written; + } + return 1; +} + +static int stop_driver(TermKey *tk, void *info) +{ + TermKeyTI *ti = info; + struct stat statbuf; + char *stop_string = ti->stop_string; + size_t len; + + if(tk->fd == -1 || !stop_string) + return 1; + + /* There's no point trying to write() to a pipe */ + if(fstat(tk->fd, &statbuf) == -1) + return 0; + +#ifndef _WIN32 + if(S_ISFIFO(statbuf.st_mode)) + return 1; +#endif + + /* The terminfo database will contain keys in application cursor key mode. + * We may need to enable that mode + */ + + // Can't call putp or tputs because they suck and don't give us fd control + len = strlen(stop_string); + while(len) { + size_t written = write(tk->fd, stop_string, len); + if(written == -1) + return 0; + stop_string += written; + len -= written; + } + return 1; +} + +static void free_driver(void *info) +{ + TermKeyTI *ti = info; + + free_trie(ti->root); + + if(ti->start_string) + free(ti->start_string); + + if(ti->stop_string) + free(ti->stop_string); + +#ifdef HAVE_UNIBILIUM + if(ti->unibi) + unibi_destroy(ti->unibi); +#else + if(ti->term) + free(ti->term); +#endif + + free(ti); +} + +#define CHARAT(i) (tk->buffer[tk->buffstart + (i)]) + +static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep) +{ + TermKeyTI *ti = info; + + if(tk->buffcount == 0) + return tk->is_closed ? TERMKEY_RES_EOF : TERMKEY_RES_NONE; + + struct trie_node *p = ti->root; + + unsigned int pos = 0; + while(pos < tk->buffcount) { + p = lookup_next(p, CHARAT(pos)); + if(!p) + break; + + pos++; + + if(p->type != TYPE_KEY) + continue; + + struct trie_node_key *nk = (struct trie_node_key*)p; + if(nk->key.type == TERMKEY_TYPE_MOUSE) { + tk->buffstart += pos; + tk->buffcount -= pos; + + TermKeyResult mouse_result = (*tk->method.peekkey_mouse)(tk, key, nbytep); + + tk->buffstart -= pos; + tk->buffcount += pos; + + if(mouse_result == TERMKEY_RES_KEY) + *nbytep += pos; + + return mouse_result; + } + + key->type = nk->key.type; + key->code.sym = nk->key.sym; + key->modifiers = nk->key.modifier_set; + *nbytep = pos; + return TERMKEY_RES_KEY; + } + + // If p is not NULL then we hadn't walked off the end yet, so we have a + // partial match + if(p && !force) + return TERMKEY_RES_AGAIN; + + return TERMKEY_RES_NONE; +} + +static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node) +{ + int pos = 0; + struct trie_node *p = ti->root; + + // Unsigned because we'll be using it as an array subscript + unsigned char b; + + while((b = seq[pos])) { + struct trie_node *next = lookup_next(p, b); + if(!next) + break; + p = next; + pos++; + } + + while((b = seq[pos])) { + struct trie_node *next; + if(seq[pos+1]) + // Intermediate node + next = new_node_arr(0, 0xff); + else + // Final key node + next = node; + + if(!next) + return 0; + + switch(p->type) { + case TYPE_ARR: + { + struct trie_node_arr *nar = (struct trie_node_arr*)p; + if(b < nar->min || b > nar->max) { + fprintf(stderr, "ASSERT FAIL: Trie insert at 0x%02x is outside of extent bounds (0x%02x..0x%02x)\n", + b, nar->min, nar->max); + abort(); + } + nar->arr[b - nar->min] = next; + p = next; + break; + } + case TYPE_KEY: + fprintf(stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n"); + abort(); + } + + pos++; + } + + return 1; +} + +struct TermKeyDriver termkey_driver_ti = { + .name = "terminfo", + + .new_driver = new_driver, + .free_driver = free_driver, + + .start_driver = start_driver, + .stop_driver = stop_driver, + + .peekkey = peekkey, +}; diff --git a/src/termkey/termkey-internal.h b/src/termkey/termkey-internal.h new file mode 100644 index 0000000000..c300b02616 --- /dev/null +++ b/src/termkey/termkey-internal.h @@ -0,0 +1,112 @@ +#ifndef GUARD_TERMKEY_INTERNAL_H_ +#define GUARD_TERMKEY_INTERNAL_H_ + +#define HAVE_TERMIOS + +#ifdef _WIN32 +# undef HAVE_TERMIOS +#endif + +#include "termkey.h" + +#include +#ifdef HAVE_TERMIOS +# include +#endif + +#ifdef _MSC_VER +#include +typedef SSIZE_T ssize_t; +#endif + +struct TermKeyDriver +{ + const char *name; + void *(*new_driver)(TermKey *tk, const char *term); + void (*free_driver)(void *info); + int (*start_driver)(TermKey *tk, void *info); + int (*stop_driver)(TermKey *tk, void *info); + TermKeyResult (*peekkey)(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytes); +}; + +struct keyinfo { + TermKeyType type; + TermKeySym sym; + int modifier_mask; + int modifier_set; +}; + +struct TermKeyDriverNode; +struct TermKeyDriverNode { + struct TermKeyDriver *driver; + void *info; + struct TermKeyDriverNode *next; +}; + +struct TermKey { + int fd; + int flags; + int canonflags; + unsigned char *buffer; + size_t buffstart; // First offset in buffer + size_t buffcount; // NUMBER of entires valid in buffer + size_t buffsize; // Total malloc'ed size + size_t hightide; /* Position beyond buffstart at which peekkey() should next start + * normally 0, but see also termkey_interpret_csi */ + +#ifdef HAVE_TERMIOS + struct termios restore_termios; + char restore_termios_valid; +#endif + + TermKey_Terminfo_Getstr_Hook *ti_getstr_hook; + void *ti_getstr_hook_data; + + int waittime; // msec + + char is_closed; + char is_started; + + int nkeynames; + const char **keynames; + + // There are 32 C0 codes + struct keyinfo c0[32]; + + struct TermKeyDriverNode *drivers; + + // Now some "protected" methods for the driver to call but which we don't + // want exported as real symbols in the library + struct { + void (*emit_codepoint)(TermKey *tk, long codepoint, TermKeyKey *key); + TermKeyResult (*peekkey_simple)(TermKey *tk, TermKeyKey *key, int force, size_t *nbytes); + TermKeyResult (*peekkey_mouse)(TermKey *tk, TermKeyKey *key, size_t *nbytes); + } method; +}; + +static inline void termkey_key_get_linecol(const TermKeyKey *key, int *line, int *col) +{ + if(col) + *col = (unsigned char)key->code.mouse[1] | ((unsigned char)key->code.mouse[3] & 0x0f) << 8; + + if(line) + *line = (unsigned char)key->code.mouse[2] | ((unsigned char)key->code.mouse[3] & 0x70) << 4; +} + +static inline void termkey_key_set_linecol(TermKeyKey *key, int line, int col) +{ + if(line > 0xfff) + line = 0xfff; + + if(col > 0x7ff) + col = 0x7ff; + + key->code.mouse[1] = (line & 0x0ff); + key->code.mouse[2] = (col & 0x0ff); + key->code.mouse[3] = (line & 0xf00) >> 8 | (col & 0x300) >> 4; +} + +extern struct TermKeyDriver termkey_driver_csi; +extern struct TermKeyDriver termkey_driver_ti; + +#endif diff --git a/src/termkey/termkey.c b/src/termkey/termkey.c new file mode 100644 index 0000000000..a839533982 --- /dev/null +++ b/src/termkey/termkey.c @@ -0,0 +1,1604 @@ +#include "termkey.h" +#include "termkey-internal.h" + +#include +#include +#ifndef _WIN32 +# include +# include +# include +#endif +#include + +#include + +#ifdef _MSC_VER +# define strcaseeq(a,b) (_stricmp(a,b) == 0) +#else +# define strcaseeq(a,b) (strcasecmp(a,b) == 0) +#endif + +void termkey_check_version(int major, int minor) +{ + if(major != TERMKEY_VERSION_MAJOR) { + fprintf(stderr, "libtermkey major version mismatch; %d (wants) != %d (library)\n", + major, TERMKEY_VERSION_MAJOR); + exit(1); + } + + if(minor > TERMKEY_VERSION_MINOR) { + fprintf(stderr, "libtermkey minor version mismatch; %d (wants) > %d (library)\n", + minor, TERMKEY_VERSION_MINOR); + exit(1); + } + + // Happy +} + +static struct TermKeyDriver *drivers[] = { + &termkey_driver_ti, + &termkey_driver_csi, + NULL, +}; + +// Forwards for the "protected" methods +// static void eat_bytes(TermKey *tk, size_t count); +static void emit_codepoint(TermKey *tk, long codepoint, TermKeyKey *key); +static TermKeyResult peekkey_simple(TermKey *tk, TermKeyKey *key, int force, size_t *nbytes); +static TermKeyResult peekkey_mouse(TermKey *tk, TermKeyKey *key, size_t *nbytes); + +static TermKeySym register_c0(TermKey *tk, TermKeySym sym, unsigned char ctrl, const char *name); +static TermKeySym register_c0_full(TermKey *tk, TermKeySym sym, int modifier_set, int modifier_mask, unsigned char ctrl, const char *name); + +static struct { + TermKeySym sym; + const char *name; +} keynames[] = { + { TERMKEY_SYM_NONE, "NONE" }, + { TERMKEY_SYM_BACKSPACE, "Backspace" }, + { TERMKEY_SYM_TAB, "Tab" }, + { TERMKEY_SYM_ENTER, "Enter" }, + { TERMKEY_SYM_ESCAPE, "Escape" }, + { TERMKEY_SYM_SPACE, "Space" }, + { TERMKEY_SYM_DEL, "DEL" }, + { TERMKEY_SYM_UP, "Up" }, + { TERMKEY_SYM_DOWN, "Down" }, + { TERMKEY_SYM_LEFT, "Left" }, + { TERMKEY_SYM_RIGHT, "Right" }, + { TERMKEY_SYM_BEGIN, "Begin" }, + { TERMKEY_SYM_FIND, "Find" }, + { TERMKEY_SYM_INSERT, "Insert" }, + { TERMKEY_SYM_DELETE, "Delete" }, + { TERMKEY_SYM_SELECT, "Select" }, + { TERMKEY_SYM_PAGEUP, "PageUp" }, + { TERMKEY_SYM_PAGEDOWN, "PageDown" }, + { TERMKEY_SYM_HOME, "Home" }, + { TERMKEY_SYM_END, "End" }, + { TERMKEY_SYM_CANCEL, "Cancel" }, + { TERMKEY_SYM_CLEAR, "Clear" }, + { TERMKEY_SYM_CLOSE, "Close" }, + { TERMKEY_SYM_COMMAND, "Command" }, + { TERMKEY_SYM_COPY, "Copy" }, + { TERMKEY_SYM_EXIT, "Exit" }, + { TERMKEY_SYM_HELP, "Help" }, + { TERMKEY_SYM_MARK, "Mark" }, + { TERMKEY_SYM_MESSAGE, "Message" }, + { TERMKEY_SYM_MOVE, "Move" }, + { TERMKEY_SYM_OPEN, "Open" }, + { TERMKEY_SYM_OPTIONS, "Options" }, + { TERMKEY_SYM_PRINT, "Print" }, + { TERMKEY_SYM_REDO, "Redo" }, + { TERMKEY_SYM_REFERENCE, "Reference" }, + { TERMKEY_SYM_REFRESH, "Refresh" }, + { TERMKEY_SYM_REPLACE, "Replace" }, + { TERMKEY_SYM_RESTART, "Restart" }, + { TERMKEY_SYM_RESUME, "Resume" }, + { TERMKEY_SYM_SAVE, "Save" }, + { TERMKEY_SYM_SUSPEND, "Suspend" }, + { TERMKEY_SYM_UNDO, "Undo" }, + { TERMKEY_SYM_KP0, "KP0" }, + { TERMKEY_SYM_KP1, "KP1" }, + { TERMKEY_SYM_KP2, "KP2" }, + { TERMKEY_SYM_KP3, "KP3" }, + { TERMKEY_SYM_KP4, "KP4" }, + { TERMKEY_SYM_KP5, "KP5" }, + { TERMKEY_SYM_KP6, "KP6" }, + { TERMKEY_SYM_KP7, "KP7" }, + { TERMKEY_SYM_KP8, "KP8" }, + { TERMKEY_SYM_KP9, "KP9" }, + { TERMKEY_SYM_KPENTER, "KPEnter" }, + { TERMKEY_SYM_KPPLUS, "KPPlus" }, + { TERMKEY_SYM_KPMINUS, "KPMinus" }, + { TERMKEY_SYM_KPMULT, "KPMult" }, + { TERMKEY_SYM_KPDIV, "KPDiv" }, + { TERMKEY_SYM_KPCOMMA, "KPComma" }, + { TERMKEY_SYM_KPPERIOD, "KPPeriod" }, + { TERMKEY_SYM_KPEQUALS, "KPEquals" }, + { 0, NULL }, +}; + +// Mouse event names +static const char *evnames[] = { "Unknown", "Press", "Drag", "Release" }; + +#define CHARAT(i) (tk->buffer[tk->buffstart + (i)]) + +#ifdef DEBUG +/* Some internal debugging functions */ + +static void print_buffer(TermKey *tk) +{ + int i; + for(i = 0; i < tk->buffcount && i < 20; i++) + fprintf(stderr, "%02x ", CHARAT(i)); + if(tk->buffcount > 20) + fprintf(stderr, "..."); +} + +static void print_key(TermKey *tk, TermKeyKey *key) +{ + switch(key->type) { + case TERMKEY_TYPE_UNICODE: + fprintf(stderr, "Unicode codepoint=U+%04lx utf8='%s'", key->code.codepoint, key->utf8); + break; + case TERMKEY_TYPE_FUNCTION: + fprintf(stderr, "Function F%d", key->code.number); + break; + case TERMKEY_TYPE_KEYSYM: + fprintf(stderr, "Keysym sym=%d(%s)", key->code.sym, termkey_get_keyname(tk, key->code.sym)); + break; + case TERMKEY_TYPE_MOUSE: + { + TermKeyMouseEvent ev; + int button, line, col; + termkey_interpret_mouse(tk, key, &ev, &button, &line, &col); + fprintf(stderr, "Mouse ev=%d button=%d pos=(%d,%d)\n", ev, button, line, col); + } + break; + case TERMKEY_TYPE_POSITION: + { + int line, col; + termkey_interpret_position(tk, key, &line, &col); + fprintf(stderr, "Position report pos=(%d,%d)\n", line, col); + } + break; + case TERMKEY_TYPE_MODEREPORT: + { + int initial, mode, value; + termkey_interpret_modereport(tk, key, &initial, &mode, &value); + fprintf(stderr, "Mode report mode=%s %d val=%d\n", initial == '?' ? "DEC" : "ANSI", mode, value); + } + break; + case TERMKEY_TYPE_DCS: + fprintf(stderr, "Device Control String"); + break; + case TERMKEY_TYPE_OSC: + fprintf(stderr, "Operating System Control"); + break; + case TERMKEY_TYPE_UNKNOWN_CSI: + fprintf(stderr, "unknown CSI\n"); + break; + } + + int m = key->modifiers; + fprintf(stderr, " mod=%s%s%s+%02x", + (m & TERMKEY_KEYMOD_CTRL ? "C" : ""), + (m & TERMKEY_KEYMOD_ALT ? "A" : ""), + (m & TERMKEY_KEYMOD_SHIFT ? "S" : ""), + m & ~(TERMKEY_KEYMOD_CTRL|TERMKEY_KEYMOD_ALT|TERMKEY_KEYMOD_SHIFT)); +} + +static const char *res2str(TermKeyResult res) +{ + static char errorbuffer[256]; + + switch(res) { + case TERMKEY_RES_KEY: + return "TERMKEY_RES_KEY"; + case TERMKEY_RES_EOF: + return "TERMKEY_RES_EOF"; + case TERMKEY_RES_AGAIN: + return "TERMKEY_RES_AGAIN"; + case TERMKEY_RES_NONE: + return "TERMKEY_RES_NONE"; + case TERMKEY_RES_ERROR: + snprintf(errorbuffer, sizeof errorbuffer, "TERMKEY_RES_ERROR(errno=%d)\n", errno); + return (const char*)errorbuffer; + } + + return "unknown"; +} +#endif + +/* Similar to snprintf(str, size, "%s", src) except it turns CamelCase into + * space separated values + */ +static int snprint_cameltospaces(char *str, size_t size, const char *src) +{ + int prev_lower = 0; + size_t l = 0; + while(*src && l < size - 1) { + if(isupper(*src) && prev_lower) { + if(str) + str[l++] = ' '; + if(l >= size - 1) + break; + } + prev_lower = islower(*src); + str[l++] = tolower(*src++); + } + str[l] = 0; + /* For consistency with snprintf, return the number of bytes that would have + * been written, excluding '\0' */ + while(*src) { + if(isupper(*src) && prev_lower) { + l++; + } + prev_lower = islower(*src); + src++; l++; + } + return l; +} + +/* Similar to strcmp(str, strcamel, n) except that: + * it compares CamelCase in strcamel with space separated values in str; + * it takes char**s and updates them + * n counts bytes of strcamel, not str + */ +static int strpncmp_camel(const char **strp, const char **strcamelp, size_t n) +{ + const char *str = *strp, *strcamel = *strcamelp; + int prev_lower = 0; + + for( ; (*str || *strcamel) && n; n--) { + char b = tolower(*strcamel); + if(isupper(*strcamel) && prev_lower) { + if(*str != ' ') + break; + str++; + if(*str != b) + break; + } + else + if(*str != b) + break; + + prev_lower = islower(*strcamel); + + str++; + strcamel++; + } + + *strp = str; + *strcamelp = strcamel; + return *str - *strcamel; +} + +static TermKey *termkey_alloc(void) +{ + TermKey *tk = malloc(sizeof(TermKey)); + if(!tk) + return NULL; + + /* Default all the object fields but don't allocate anything */ + + tk->fd = -1; + tk->flags = 0; + tk->canonflags = 0; + + tk->buffer = NULL; + tk->buffstart = 0; + tk->buffcount = 0; + tk->buffsize = 256; /* bytes */ + tk->hightide = 0; + +#ifdef HAVE_TERMIOS + tk->restore_termios_valid = 0; +#endif + + tk->ti_getstr_hook = NULL; + tk->ti_getstr_hook_data = NULL; + + tk->waittime = 50; /* msec */ + + tk->is_closed = 0; + tk->is_started = 0; + + tk->nkeynames = 64; + tk->keynames = NULL; + + for(int i = 0; i < 32; i++) + tk->c0[i].sym = TERMKEY_SYM_NONE; + + tk->drivers = NULL; + + tk->method.emit_codepoint = &emit_codepoint; + tk->method.peekkey_simple = &peekkey_simple; + tk->method.peekkey_mouse = &peekkey_mouse; + + return tk; +} + +static int termkey_init(TermKey *tk, const char *term) +{ + tk->buffer = malloc(tk->buffsize); + if(!tk->buffer) + return 0; + + tk->keynames = malloc(sizeof(tk->keynames[0]) * tk->nkeynames); + if(!tk->keynames) + goto abort_free_buffer; + + int i; + for(i = 0; i < tk->nkeynames; i++) + tk->keynames[i] = NULL; + + for(i = 0; keynames[i].name; i++) + if(termkey_register_keyname(tk, keynames[i].sym, keynames[i].name) == -1) + goto abort_free_keynames; + + register_c0(tk, TERMKEY_SYM_TAB, 0x09, NULL); + register_c0(tk, TERMKEY_SYM_ENTER, 0x0d, NULL); + register_c0(tk, TERMKEY_SYM_ESCAPE, 0x1b, NULL); + + struct TermKeyDriverNode *tail = NULL; + + for(i = 0; drivers[i]; i++) { + void *info = (*drivers[i]->new_driver)(tk, term); + if(!info) + continue; + +#ifdef DEBUG + fprintf(stderr, "Loading the %s driver...\n", drivers[i]->name); +#endif + + struct TermKeyDriverNode *thisdrv = malloc(sizeof(*thisdrv)); + if(!thisdrv) + goto abort_free_drivers; + + thisdrv->driver = drivers[i]; + thisdrv->info = info; + thisdrv->next = NULL; + + if(!tail) + tk->drivers = thisdrv; + else + tail->next = thisdrv; + + tail = thisdrv; + +#ifdef DEBUG + fprintf(stderr, "Loaded %s driver\n", drivers[i]->name); +#endif + } + + if(!tk->drivers) { + errno = ENOENT; + goto abort_free_keynames; + } + + return 1; + +abort_free_drivers: + for(struct TermKeyDriverNode *p = tk->drivers; p; ) { + (*p->driver->free_driver)(p->info); + struct TermKeyDriverNode *next = p->next; + free(p); + p = next; + } + +abort_free_keynames: + free(tk->keynames); + +abort_free_buffer: + free(tk->buffer); + + return 0; +} + +TermKey *termkey_new(int fd, int flags) +{ + TermKey *tk = termkey_alloc(); + if(!tk) + return NULL; + + tk->fd = fd; + + if(!(flags & (TERMKEY_FLAG_RAW|TERMKEY_FLAG_UTF8))) { + char *e; + + /* Most OSes will set .UTF-8. Some will set .utf8. Try to be fairly + * generous in parsing these + */ + if(((e = getenv("LANG")) || (e = getenv("LC_MESSAGES")) || (e = getenv("LC_ALL"))) && + (e = strchr(e, '.')) && e++ && + (strcaseeq(e, "UTF-8") || strcaseeq(e, "UTF8"))) + flags |= TERMKEY_FLAG_UTF8; + else + flags |= TERMKEY_FLAG_RAW; + } + + termkey_set_flags(tk, flags); + + const char *term = getenv("TERM"); + + if(!termkey_init(tk, term)) + goto abort; + + if(!(flags & TERMKEY_FLAG_NOSTART) && !termkey_start(tk)) + goto abort; + + return tk; + +abort: + free(tk); + return NULL; +} + +TermKey *termkey_new_abstract(const char *term, int flags) +{ + TermKey *tk = termkey_alloc(); + if(!tk) + return NULL; + + tk->fd = -1; + + termkey_set_flags(tk, flags); + + if(!termkey_init(tk, term)) { + free(tk); + return NULL; + } + + if(!(flags & TERMKEY_FLAG_NOSTART) && !termkey_start(tk)) + goto abort; + + return tk; + +abort: + free(tk); + return NULL; +} + +void termkey_free(TermKey *tk) +{ + free(tk->buffer); tk->buffer = NULL; + free(tk->keynames); tk->keynames = NULL; + + struct TermKeyDriverNode *p; + for(p = tk->drivers; p; ) { + (*p->driver->free_driver)(p->info); + struct TermKeyDriverNode *next = p->next; + free(p); + p = next; + } + + free(tk); +} + +void termkey_destroy(TermKey *tk) +{ + if(tk->is_started) + termkey_stop(tk); + + termkey_free(tk); +} + +void termkey_hook_terminfo_getstr(TermKey *tk, TermKey_Terminfo_Getstr_Hook *hookfn, void *data) +{ + tk->ti_getstr_hook = hookfn; + tk->ti_getstr_hook_data = data; +} + +int termkey_start(TermKey *tk) +{ + if(tk->is_started) + return 1; + +#ifdef HAVE_TERMIOS + if(tk->fd != -1 && !(tk->flags & TERMKEY_FLAG_NOTERMIOS)) { + struct termios termios; + if(tcgetattr(tk->fd, &termios) == 0) { + tk->restore_termios = termios; + tk->restore_termios_valid = 1; + + termios.c_iflag &= ~(IXON|INLCR|ICRNL); + termios.c_lflag &= ~(ICANON|ECHO +#ifdef IEXTEN + | IEXTEN +#endif + ); + termios.c_cc[VMIN] = 1; + termios.c_cc[VTIME] = 0; + + if(tk->flags & TERMKEY_FLAG_CTRLC) + /* want no signal keys at all, so just disable ISIG */ + termios.c_lflag &= ~ISIG; + else { + /* Disable Ctrl-\==VQUIT and Ctrl-D==VSUSP but leave Ctrl-C as SIGINT */ + termios.c_cc[VQUIT] = _POSIX_VDISABLE; + termios.c_cc[VSUSP] = _POSIX_VDISABLE; + /* Some OSes have Ctrl-Y==VDSUSP */ +#ifdef VDSUSP + termios.c_cc[VDSUSP] = _POSIX_VDISABLE; +#endif + } + +#ifdef DEBUG + fprintf(stderr, "Setting termios(3) flags\n"); +#endif + tcsetattr(tk->fd, TCSANOW, &termios); + } + } +#endif + + struct TermKeyDriverNode *p; + for(p = tk->drivers; p; p = p->next) + if(p->driver->start_driver) + if(!(*p->driver->start_driver)(tk, p->info)) + return 0; + +#ifdef DEBUG + fprintf(stderr, "Drivers started; termkey instance %p is ready\n", tk); +#endif + + tk->is_started = 1; + return 1; +} + +int termkey_stop(TermKey *tk) +{ + if(!tk->is_started) + return 1; + + struct TermKeyDriverNode *p; + for(p = tk->drivers; p; p = p->next) + if(p->driver->stop_driver) + (*p->driver->stop_driver)(tk, p->info); + +#ifdef HAVE_TERMIOS + if(tk->restore_termios_valid) + tcsetattr(tk->fd, TCSANOW, &tk->restore_termios); +#endif + + tk->is_started = 0; + + return 1; +} + +int termkey_is_started(TermKey *tk) +{ + return tk->is_started; +} + +int termkey_get_fd(TermKey *tk) +{ + return tk->fd; +} + +int termkey_get_flags(TermKey *tk) +{ + return tk->flags; +} + +void termkey_set_flags(TermKey *tk, int newflags) +{ + tk->flags = newflags; + + if(tk->flags & TERMKEY_FLAG_SPACESYMBOL) + tk->canonflags |= TERMKEY_CANON_SPACESYMBOL; + else + tk->canonflags &= ~TERMKEY_CANON_SPACESYMBOL; +} + +void termkey_set_waittime(TermKey *tk, int msec) +{ + tk->waittime = msec; +} + +int termkey_get_waittime(TermKey *tk) +{ + return tk->waittime; +} + +int termkey_get_canonflags(TermKey *tk) +{ + return tk->canonflags; +} + +void termkey_set_canonflags(TermKey *tk, int flags) +{ + tk->canonflags = flags; + + if(tk->canonflags & TERMKEY_CANON_SPACESYMBOL) + tk->flags |= TERMKEY_FLAG_SPACESYMBOL; + else + tk->flags &= ~TERMKEY_FLAG_SPACESYMBOL; +} + +size_t termkey_get_buffer_size(TermKey *tk) +{ + return tk->buffsize; +} + +int termkey_set_buffer_size(TermKey *tk, size_t size) +{ + unsigned char *buffer = realloc(tk->buffer, size); + if(!buffer) + return 0; + + tk->buffer = buffer; + tk->buffsize = size; + + return 1; +} + +size_t termkey_get_buffer_remaining(TermKey *tk) +{ + /* Return the total number of free bytes in the buffer, because that's what + * is available to the user. */ + return tk->buffsize - tk->buffcount; +} + +static void eat_bytes(TermKey *tk, size_t count) +{ + if(count >= tk->buffcount) { + tk->buffstart = 0; + tk->buffcount = 0; + return; + } + + tk->buffstart += count; + tk->buffcount -= count; +} + +static inline unsigned int utf8_seqlen(long codepoint) +{ + if(codepoint < 0x0000080) return 1; + if(codepoint < 0x0000800) return 2; + if(codepoint < 0x0010000) return 3; + if(codepoint < 0x0200000) return 4; + if(codepoint < 0x4000000) return 5; + return 6; +} + +static void fill_utf8(TermKeyKey *key) +{ + long codepoint = key->code.codepoint; + int nbytes = utf8_seqlen(codepoint); + + key->utf8[nbytes] = 0; + + // This is easier done backwards + int b = nbytes; + while(b > 1) { + b--; + key->utf8[b] = 0x80 | (codepoint & 0x3f); + codepoint >>= 6; + } + + switch(nbytes) { + case 1: key->utf8[0] = (codepoint & 0x7f); break; + case 2: key->utf8[0] = 0xc0 | (codepoint & 0x1f); break; + case 3: key->utf8[0] = 0xe0 | (codepoint & 0x0f); break; + case 4: key->utf8[0] = 0xf0 | (codepoint & 0x07); break; + case 5: key->utf8[0] = 0xf8 | (codepoint & 0x03); break; + case 6: key->utf8[0] = 0xfc | (codepoint & 0x01); break; + } +} + +#define UTF8_INVALID 0xFFFD +static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, long *cp, size_t *nbytep) +{ + unsigned int nbytes; + + unsigned char b0 = bytes[0]; + + if(b0 < 0x80) { + // Single byte ASCII + *cp = b0; + *nbytep = 1; + return TERMKEY_RES_KEY; + } + else if(b0 < 0xc0) { + // Starts with a continuation byte - that's not right + *cp = UTF8_INVALID; + *nbytep = 1; + return TERMKEY_RES_KEY; + } + else if(b0 < 0xe0) { + nbytes = 2; + *cp = b0 & 0x1f; + } + else if(b0 < 0xf0) { + nbytes = 3; + *cp = b0 & 0x0f; + } + else if(b0 < 0xf8) { + nbytes = 4; + *cp = b0 & 0x07; + } + else if(b0 < 0xfc) { + nbytes = 5; + *cp = b0 & 0x03; + } + else if(b0 < 0xfe) { + nbytes = 6; + *cp = b0 & 0x01; + } + else { + *cp = UTF8_INVALID; + *nbytep = 1; + return TERMKEY_RES_KEY; + } + + for(unsigned int b = 1; b < nbytes; b++) { + unsigned char cb; + + if(b >= len) + return TERMKEY_RES_AGAIN; + + cb = bytes[b]; + if(cb < 0x80 || cb >= 0xc0) { + *cp = UTF8_INVALID; + *nbytep = b; + return TERMKEY_RES_KEY; + } + + *cp <<= 6; + *cp |= cb & 0x3f; + } + + // Check for overlong sequences + if(nbytes > utf8_seqlen(*cp)) + *cp = UTF8_INVALID; + + // Check for UTF-16 surrogates or invalid *cps + if((*cp >= 0xD800 && *cp <= 0xDFFF) || + *cp == 0xFFFE || + *cp == 0xFFFF) + *cp = UTF8_INVALID; + + *nbytep = nbytes; + return TERMKEY_RES_KEY; +} + +static void emit_codepoint(TermKey *tk, long codepoint, TermKeyKey *key) +{ + if(codepoint == 0) { + // ASCII NUL = Ctrl-Space + key->type = TERMKEY_TYPE_KEYSYM; + key->code.sym = TERMKEY_SYM_SPACE; + key->modifiers = TERMKEY_KEYMOD_CTRL; + } + else if(codepoint < 0x20) { + // C0 range + key->code.codepoint = 0; + key->modifiers = 0; + + if(!(tk->flags & TERMKEY_FLAG_NOINTERPRET) && tk->c0[codepoint].sym != TERMKEY_SYM_UNKNOWN) { + key->code.sym = tk->c0[codepoint].sym; + key->modifiers |= tk->c0[codepoint].modifier_set; + } + + if(!key->code.sym) { + key->type = TERMKEY_TYPE_UNICODE; + /* Generically modified Unicode ought not report the SHIFT state, or else + * we get into complications trying to report Shift-; vs : and so on... + * In order to be able to represent Ctrl-Shift-A as CTRL modified + * unicode A, we need to call Ctrl-A simply 'a', lowercase + */ + if(codepoint+0x40 >= 'A' && codepoint+0x40 <= 'Z') + // it's a letter - use lowercase instead + key->code.codepoint = codepoint + 0x60; + else + key->code.codepoint = codepoint + 0x40; + key->modifiers = TERMKEY_KEYMOD_CTRL; + } + else { + key->type = TERMKEY_TYPE_KEYSYM; + } + } + else if(codepoint == 0x7f && !(tk->flags & TERMKEY_FLAG_NOINTERPRET)) { + // ASCII DEL + key->type = TERMKEY_TYPE_KEYSYM; + key->code.sym = TERMKEY_SYM_DEL; + key->modifiers = 0; + } + else if(codepoint >= 0x20 && codepoint < 0x80) { + // ASCII lowbyte range + key->type = TERMKEY_TYPE_UNICODE; + key->code.codepoint = codepoint; + key->modifiers = 0; + } + else if(codepoint >= 0x80 && codepoint < 0xa0) { + // UTF-8 never starts with a C1 byte. So we can be sure of these + key->type = TERMKEY_TYPE_UNICODE; + key->code.codepoint = codepoint - 0x40; + key->modifiers = TERMKEY_KEYMOD_CTRL|TERMKEY_KEYMOD_ALT; + } + else { + // UTF-8 codepoint + key->type = TERMKEY_TYPE_UNICODE; + key->code.codepoint = codepoint; + key->modifiers = 0; + } + + termkey_canonicalise(tk, key); + + if(key->type == TERMKEY_TYPE_UNICODE) + fill_utf8(key); +} + +void termkey_canonicalise(TermKey *tk, TermKeyKey *key) +{ + int flags = tk->canonflags; + + if(flags & TERMKEY_CANON_SPACESYMBOL) { + if(key->type == TERMKEY_TYPE_UNICODE && key->code.codepoint == 0x20) { + key->type = TERMKEY_TYPE_KEYSYM; + key->code.sym = TERMKEY_SYM_SPACE; + } + } + else { + if(key->type == TERMKEY_TYPE_KEYSYM && key->code.sym == TERMKEY_SYM_SPACE) { + key->type = TERMKEY_TYPE_UNICODE; + key->code.codepoint = 0x20; + fill_utf8(key); + } + } + + if(flags & TERMKEY_CANON_DELBS) { + if(key->type == TERMKEY_TYPE_KEYSYM && key->code.sym == TERMKEY_SYM_DEL) { + key->code.sym = TERMKEY_SYM_BACKSPACE; + } + } +} + +static TermKeyResult peekkey(TermKey *tk, TermKeyKey *key, int force, size_t *nbytep) +{ + int again = 0; + + if(!tk->is_started) { + errno = EINVAL; + return TERMKEY_RES_ERROR; + } + +#ifdef DEBUG + fprintf(stderr, "getkey(force=%d): buffer ", force); + print_buffer(tk); + fprintf(stderr, "\n"); +#endif + + if(tk->hightide) { + tk->buffstart += tk->hightide; + tk->buffcount -= tk->hightide; + tk->hightide = 0; + } + + TermKeyResult ret; + struct TermKeyDriverNode *p; + for(p = tk->drivers; p; p = p->next) { + ret = (p->driver->peekkey)(tk, p->info, key, force, nbytep); + +#ifdef DEBUG + fprintf(stderr, "Driver %s yields %s\n", p->driver->name, res2str(ret)); +#endif + + switch(ret) { + case TERMKEY_RES_KEY: +#ifdef DEBUG + print_key(tk, key); fprintf(stderr, "\n"); +#endif + // Slide the data down to stop it running away + { + size_t halfsize = tk->buffsize / 2; + + if(tk->buffstart > halfsize) { + memcpy(tk->buffer, tk->buffer + halfsize, halfsize); + tk->buffstart -= halfsize; + } + } + + /* fallthrough */ + case TERMKEY_RES_EOF: + case TERMKEY_RES_ERROR: + return ret; + + case TERMKEY_RES_AGAIN: + if(!force) + again = 1; + + /* fallthrough */ + case TERMKEY_RES_NONE: + break; + } + } + + if(again) + return TERMKEY_RES_AGAIN; + + ret = peekkey_simple(tk, key, force, nbytep); + +#ifdef DEBUG + fprintf(stderr, "getkey_simple(force=%d) yields %s\n", force, res2str(ret)); + if(ret == TERMKEY_RES_KEY) { + print_key(tk, key); fprintf(stderr, "\n"); + } +#endif + + return ret; +} + +static TermKeyResult peekkey_simple(TermKey *tk, TermKeyKey *key, int force, size_t *nbytep) +{ + if(tk->buffcount == 0) + return tk->is_closed ? TERMKEY_RES_EOF : TERMKEY_RES_NONE; + + unsigned char b0 = CHARAT(0); + + if(b0 == 0x1b) { + // Escape-prefixed value? Might therefore be Alt+key + if(tk->buffcount == 1) { + // This might be an press, or it may want to be part of a longer + // sequence + if(!force) + return TERMKEY_RES_AGAIN; + + (*tk->method.emit_codepoint)(tk, b0, key); + *nbytep = 1; + return TERMKEY_RES_KEY; + } + + // Try another key there + tk->buffstart++; + tk->buffcount--; + + // Run the full driver + TermKeyResult metakey_result = peekkey(tk, key, force, nbytep); + + tk->buffstart--; + tk->buffcount++; + + switch(metakey_result) { + case TERMKEY_RES_KEY: + key->modifiers |= TERMKEY_KEYMOD_ALT; + (*nbytep)++; + break; + + case TERMKEY_RES_NONE: + case TERMKEY_RES_EOF: + case TERMKEY_RES_AGAIN: + case TERMKEY_RES_ERROR: + break; + } + + return metakey_result; + } + else if(b0 < 0xa0) { + // Single byte C0, G0 or C1 - C1 is never UTF-8 initial byte + (*tk->method.emit_codepoint)(tk, b0, key); + *nbytep = 1; + return TERMKEY_RES_KEY; + } + else if(tk->flags & TERMKEY_FLAG_UTF8) { + // Some UTF-8 + long codepoint; + TermKeyResult res = parse_utf8(tk->buffer + tk->buffstart, tk->buffcount, &codepoint, nbytep); + + if(res == TERMKEY_RES_AGAIN && force) { + /* There weren't enough bytes for a complete UTF-8 sequence but caller + * demands an answer. About the best thing we can do here is eat as many + * bytes as we have, and emit a UTF8_INVALID. If the remaining bytes + * arrive later, they'll be invalid too. + */ + codepoint = UTF8_INVALID; + *nbytep = tk->buffcount; + res = TERMKEY_RES_KEY; + } + + key->type = TERMKEY_TYPE_UNICODE; + key->modifiers = 0; + (*tk->method.emit_codepoint)(tk, codepoint, key); + return res; + } + else { + // Non UTF-8 case - just report the raw byte + key->type = TERMKEY_TYPE_UNICODE; + key->code.codepoint = b0; + key->modifiers = 0; + + key->utf8[0] = key->code.codepoint; + key->utf8[1] = 0; + + *nbytep = 1; + + return TERMKEY_RES_KEY; + } +} + +static TermKeyResult peekkey_mouse(TermKey *tk, TermKeyKey *key, size_t *nbytep) +{ + if(tk->buffcount < 3) + return TERMKEY_RES_AGAIN; + + key->type = TERMKEY_TYPE_MOUSE; + key->code.mouse[0] = CHARAT(0) - 0x20; + key->code.mouse[1] = CHARAT(1) - 0x20; + key->code.mouse[2] = CHARAT(2) - 0x20; + key->code.mouse[3] = 0; + + key->modifiers = (key->code.mouse[0] & 0x1c) >> 2; + key->code.mouse[0] &= ~0x1c; + + *nbytep = 3; + return TERMKEY_RES_KEY; +} + +TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key) +{ + size_t nbytes = 0; + TermKeyResult ret = peekkey(tk, key, 0, &nbytes); + + if(ret == TERMKEY_RES_KEY) + eat_bytes(tk, nbytes); + + if(ret == TERMKEY_RES_AGAIN) + /* Call peekkey() again in force mode to obtain whatever it can */ + (void)peekkey(tk, key, 1, &nbytes); + /* Don't eat it yet though */ + + return ret; +} + +TermKeyResult termkey_getkey_force(TermKey *tk, TermKeyKey *key) +{ + size_t nbytes = 0; + TermKeyResult ret = peekkey(tk, key, 1, &nbytes); + + if(ret == TERMKEY_RES_KEY) + eat_bytes(tk, nbytes); + + return ret; +} + +#ifndef _WIN32 +TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key) +{ + if(tk->fd == -1) { + errno = EBADF; + return TERMKEY_RES_ERROR; + } + + while(1) { + TermKeyResult ret = termkey_getkey(tk, key); + + switch(ret) { + case TERMKEY_RES_KEY: + case TERMKEY_RES_EOF: + case TERMKEY_RES_ERROR: + return ret; + + case TERMKEY_RES_NONE: + ret = termkey_advisereadable(tk); + if(ret == TERMKEY_RES_ERROR) + return ret; + break; + + case TERMKEY_RES_AGAIN: + { + if(tk->is_closed) + // We're closed now. Never going to get more bytes so just go with + // what we have + return termkey_getkey_force(tk, key); + + struct pollfd fd; + +retry: + fd.fd = tk->fd; + fd.events = POLLIN; + + int pollret = poll(&fd, 1, tk->waittime); + if(pollret == -1) { + if(errno == EINTR && !(tk->flags & TERMKEY_FLAG_EINTR)) + goto retry; + + return TERMKEY_RES_ERROR; + } + + if(fd.revents & (POLLIN|POLLHUP|POLLERR)) + ret = termkey_advisereadable(tk); + else + ret = TERMKEY_RES_NONE; + + if(ret == TERMKEY_RES_ERROR) + return ret; + if(ret == TERMKEY_RES_NONE) + return termkey_getkey_force(tk, key); + } + break; + } + } + + /* UNREACHABLE */ +} +#endif + +TermKeyResult termkey_advisereadable(TermKey *tk) +{ + ssize_t len; + + if(tk->fd == -1) { + errno = EBADF; + return TERMKEY_RES_ERROR; + } + + if(tk->buffstart) { + memmove(tk->buffer, tk->buffer + tk->buffstart, tk->buffcount); + tk->buffstart = 0; + } + + /* Not expecting it ever to be greater but doesn't hurt to handle that */ + if(tk->buffcount >= tk->buffsize) { + errno = ENOMEM; + return TERMKEY_RES_ERROR; + } + +retry: + len = read(tk->fd, tk->buffer + tk->buffcount, tk->buffsize - tk->buffcount); + + if(len == -1) { + if(errno == EAGAIN) + return TERMKEY_RES_NONE; + else if(errno == EINTR && !(tk->flags & TERMKEY_FLAG_EINTR)) + goto retry; + else + return TERMKEY_RES_ERROR; + } + else if(len < 1) { + tk->is_closed = 1; + return TERMKEY_RES_NONE; + } + else { + tk->buffcount += len; + return TERMKEY_RES_AGAIN; + } +} + +size_t termkey_push_bytes(TermKey *tk, const char *bytes, size_t len) +{ + if(tk->buffstart) { + memmove(tk->buffer, tk->buffer + tk->buffstart, tk->buffcount); + tk->buffstart = 0; + } + + /* Not expecting it ever to be greater but doesn't hurt to handle that */ + if(tk->buffcount >= tk->buffsize) { + errno = ENOMEM; + return (size_t)-1; + } + + if(len > tk->buffsize - tk->buffcount) + len = tk->buffsize - tk->buffcount; + + // memcpy(), not strncpy() in case of null bytes in input + memcpy(tk->buffer + tk->buffcount, bytes, len); + tk->buffcount += len; + + return len; +} + +TermKeySym termkey_register_keyname(TermKey *tk, TermKeySym sym, const char *name) +{ + if(!sym) + sym = tk->nkeynames; + + if(sym >= tk->nkeynames) { + const char **new_keynames = realloc(tk->keynames, sizeof(new_keynames[0]) * (sym + 1)); + if(!new_keynames) + return -1; + + tk->keynames = new_keynames; + + // Fill in the hole + for(int i = tk->nkeynames; i < sym; i++) + tk->keynames[i] = NULL; + + tk->nkeynames = sym + 1; + } + + tk->keynames[sym] = name; + + return sym; +} + +const char *termkey_get_keyname(TermKey *tk, TermKeySym sym) +{ + if(sym == TERMKEY_SYM_UNKNOWN) + return "UNKNOWN"; + + if(sym < tk->nkeynames) + return tk->keynames[sym]; + + return "UNKNOWN"; +} + +static const char *termkey_lookup_keyname_format(TermKey *tk, const char *str, TermKeySym *sym, TermKeyFormat format) +{ + /* We store an array, so we can't do better than a linear search. Doesn't + * matter because user won't be calling this too often */ + + for(*sym = 0; *sym < tk->nkeynames; (*sym)++) { + const char *thiskey = tk->keynames[*sym]; + if(!thiskey) + continue; + size_t len = strlen(thiskey); + if(format & TERMKEY_FORMAT_LOWERSPACE) { + const char *thisstr = str; + if(strpncmp_camel(&thisstr, &thiskey, len) == 0) + return thisstr; + } + else { + if(strncmp(str, thiskey, len) == 0) + return (char *)str + len; + } + } + + return NULL; +} + +const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym) +{ + return termkey_lookup_keyname_format(tk, str, sym, 0); +} + +TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname) +{ + TermKeySym sym; + const char *endp = termkey_lookup_keyname(tk, keyname, &sym); + if(!endp || endp[0]) + return TERMKEY_SYM_UNKNOWN; + return sym; +} + +static TermKeySym register_c0(TermKey *tk, TermKeySym sym, unsigned char ctrl, const char *name) +{ + return register_c0_full(tk, sym, 0, 0, ctrl, name); +} + +static TermKeySym register_c0_full(TermKey *tk, TermKeySym sym, int modifier_set, int modifier_mask, unsigned char ctrl, const char *name) +{ + if(ctrl >= 0x20) { + errno = EINVAL; + return -1; + } + + if(name) + sym = termkey_register_keyname(tk, sym, name); + + tk->c0[ctrl].sym = sym; + tk->c0[ctrl].modifier_set = modifier_set; + tk->c0[ctrl].modifier_mask = modifier_mask; + + return sym; +} + +/* Previous name for this function + * No longer declared in termkey.h but it remains in the compiled library for + * backward-compatibility reasons. + */ +size_t termkey_snprint_key(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, TermKeyFormat format) +{ + return termkey_strfkey(tk, buffer, len, key, format); +} + +static struct modnames { + const char *shift, *alt, *ctrl; +} +modnames[] = { + { "S", "A", "C" }, // 0 + { "Shift", "Alt", "Ctrl" }, // LONGMOD + { "S", "M", "C" }, // ALTISMETA + { "Shift", "Meta", "Ctrl" }, // ALTISMETA+LONGMOD + { "s", "a", "c" }, // LOWERMOD + { "shift", "alt", "ctrl" }, // LOWERMOD+LONGMOD + { "s", "m", "c" }, // LOWERMOD+ALTISMETA + { "shift", "meta", "ctrl" }, // LOWERMOD+ALTISMETA+LONGMOD +}; + +size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, TermKeyFormat format) +{ + size_t pos = 0; + size_t l = 0; + + struct modnames *mods = &modnames[!!(format & TERMKEY_FORMAT_LONGMOD) + + !!(format & TERMKEY_FORMAT_ALTISMETA) * 2 + + !!(format & TERMKEY_FORMAT_LOWERMOD) * 4]; + + int wrapbracket = (format & TERMKEY_FORMAT_WRAPBRACKET) && + (key->type != TERMKEY_TYPE_UNICODE || key->modifiers != 0); + + char sep = (format & TERMKEY_FORMAT_SPACEMOD) ? ' ' : '-'; + + if(format & TERMKEY_FORMAT_CARETCTRL && + key->type == TERMKEY_TYPE_UNICODE && + key->modifiers == TERMKEY_KEYMOD_CTRL) { + long codepoint = key->code.codepoint; + + // Handle some of the special cases first + if(codepoint >= 'a' && codepoint <= 'z') { + l = snprintf(buffer + pos, len - pos, wrapbracket ? "<^%c>" : "^%c", (char)codepoint - 0x20); + if(l <= 0) return pos; + pos += l; + return pos; + } + else if((codepoint >= '@' && codepoint < 'A') || + (codepoint > 'Z' && codepoint <= '_')) { + l = snprintf(buffer + pos, len - pos, wrapbracket ? "<^%c>" : "^%c", (char)codepoint); + if(l <= 0) return pos; + pos += l; + return pos; + } + } + + if(wrapbracket) { + l = snprintf(buffer + pos, len - pos, "<"); + if(l <= 0) return pos; + pos += l; + } + + if(key->modifiers & TERMKEY_KEYMOD_ALT) { + l = snprintf(buffer + pos, len - pos, "%s%c", mods->alt, sep); + if(l <= 0) return pos; + pos += l; + } + + if(key->modifiers & TERMKEY_KEYMOD_CTRL) { + l = snprintf(buffer + pos, len - pos, "%s%c", mods->ctrl, sep); + if(l <= 0) return pos; + pos += l; + } + + if(key->modifiers & TERMKEY_KEYMOD_SHIFT) { + l = snprintf(buffer + pos, len - pos, "%s%c", mods->shift, sep); + if(l <= 0) return pos; + pos += l; + } + + switch(key->type) { + case TERMKEY_TYPE_UNICODE: + if(!key->utf8[0]) // In case of user-supplied key structures + fill_utf8(key); + l = snprintf(buffer + pos, len - pos, "%s", key->utf8); + break; + case TERMKEY_TYPE_KEYSYM: + { + const char *name = termkey_get_keyname(tk, key->code.sym); + if(format & TERMKEY_FORMAT_LOWERSPACE) + l = snprint_cameltospaces(buffer + pos, len - pos, name); + else + l = snprintf(buffer + pos, len - pos, "%s", name); + } + break; + case TERMKEY_TYPE_FUNCTION: + l = snprintf(buffer + pos, len - pos, "%c%d", + (format & TERMKEY_FORMAT_LOWERSPACE ? 'f' : 'F'), key->code.number); + break; + case TERMKEY_TYPE_MOUSE: + { + TermKeyMouseEvent ev; + int button; + int line, col; + termkey_interpret_mouse(tk, key, &ev, &button, &line, &col); + + l = snprintf(buffer + pos, len - pos, "Mouse%s(%d)", + evnames[ev], button); + + if(format & TERMKEY_FORMAT_MOUSE_POS) { + if(l <= 0) return pos; + pos += l; + + l = snprintf(buffer + pos, len - pos, " @ (%u,%u)", col, line); + } + } + break; + case TERMKEY_TYPE_POSITION: + l = snprintf(buffer + pos, len - pos, "Position"); + break; + case TERMKEY_TYPE_MODEREPORT: + { + int initial, mode, value; + termkey_interpret_modereport(tk, key, &initial, &mode, &value); + if(initial) + l = snprintf(buffer + pos, len - pos, "Mode(%c%d=%d)", initial, mode, value); + else + l = snprintf(buffer + pos, len - pos, "Mode(%d=%d)", mode, value); + } + case TERMKEY_TYPE_DCS: + l = snprintf(buffer + pos, len - pos, "DCS"); + break; + case TERMKEY_TYPE_OSC: + l = snprintf(buffer + pos, len - pos, "OSC"); + break; + case TERMKEY_TYPE_UNKNOWN_CSI: + l = snprintf(buffer + pos, len - pos, "CSI %c", key->code.number & 0xff); + break; + } + + if(l <= 0) return pos; + pos += l; + + if(wrapbracket) { + l = snprintf(buffer + pos, len - pos, ">"); + if(l <= 0) return pos; + pos += l; + } + + return pos; +} + +const char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermKeyFormat format) +{ + struct modnames *mods = &modnames[!!(format & TERMKEY_FORMAT_LONGMOD) + + !!(format & TERMKEY_FORMAT_ALTISMETA) * 2 + + !!(format & TERMKEY_FORMAT_LOWERMOD) * 4]; + + key->modifiers = 0; + + if((format & TERMKEY_FORMAT_CARETCTRL) && str[0] == '^' && str[1]) { + str = termkey_strpkey(tk, str+1, key, format & ~TERMKEY_FORMAT_CARETCTRL); + + if(!str || + key->type != TERMKEY_TYPE_UNICODE || + key->code.codepoint < '@' || key->code.codepoint > '_' || + key->modifiers != 0) + return NULL; + + if(key->code.codepoint >= 'A' && key->code.codepoint <= 'Z') + key->code.codepoint += 0x20; + key->modifiers = TERMKEY_KEYMOD_CTRL; + fill_utf8(key); + return (char *)str; + } + + const char *sep_at; + + while((sep_at = strchr(str, (format & TERMKEY_FORMAT_SPACEMOD) ? ' ' : '-'))) { + size_t n = sep_at - str; + + if(n == strlen(mods->alt) && strncmp(mods->alt, str, n) == 0) + key->modifiers |= TERMKEY_KEYMOD_ALT; + else if(n == strlen(mods->ctrl) && strncmp(mods->ctrl, str, n) == 0) + key->modifiers |= TERMKEY_KEYMOD_CTRL; + else if(n == strlen(mods->shift) && strncmp(mods->shift, str, n) == 0) + key->modifiers |= TERMKEY_KEYMOD_SHIFT; + + else + break; + + str = sep_at + 1; + } + + size_t nbytes; + ssize_t snbytes; + const char *endstr; + int button; + char event_name[32]; + + if((endstr = termkey_lookup_keyname_format(tk, str, &key->code.sym, format))) { + key->type = TERMKEY_TYPE_KEYSYM; + str = endstr; + } + else if(sscanf(str, "F%d%zn", &key->code.number, &snbytes) == 1) { + key->type = TERMKEY_TYPE_FUNCTION; + str += snbytes; + } + else if(sscanf(str, "Mouse%31[^(](%d)%zn", event_name, &button, &snbytes) == 2) { + str += snbytes; + key->type = TERMKEY_TYPE_MOUSE; + + TermKeyMouseEvent ev = TERMKEY_MOUSE_UNKNOWN; + for(size_t i = 0; i < sizeof(evnames)/sizeof(evnames[0]); i++) { + if(strcmp(evnames[i], event_name) == 0) { + ev = TERMKEY_MOUSE_UNKNOWN + i; + break; + } + } + + int code; + switch(ev) { + case TERMKEY_MOUSE_PRESS: + case TERMKEY_MOUSE_DRAG: + code = button - 1; + if(ev == TERMKEY_MOUSE_DRAG) { + code |= 0x20; + } + break; + case TERMKEY_MOUSE_RELEASE: + code = 3; + break; + default: + code = 128; + break; + } + key->code.mouse[0] = code; + + unsigned int line = 0, col = 0; + if((format & TERMKEY_FORMAT_MOUSE_POS) && sscanf(str, " @ (%u,%u)%zn", &col, &line, &snbytes) == 2) { + str += snbytes; + } + termkey_key_set_linecol(key, col, line); + } + // Unicode must be last + else if(parse_utf8((unsigned const char *)str, strlen(str), &key->code.codepoint, &nbytes) == TERMKEY_RES_KEY) { + key->type = TERMKEY_TYPE_UNICODE; + fill_utf8(key); + str += nbytes; + } + else + return NULL; + + termkey_canonicalise(tk, key); + + return (char *)str; +} + +int termkey_keycmp(TermKey *tk, const TermKeyKey *key1p, const TermKeyKey *key2p) +{ + /* Copy the key structs since we'll be modifying them */ + TermKeyKey key1 = *key1p, key2 = *key2p; + + termkey_canonicalise(tk, &key1); + termkey_canonicalise(tk, &key2); + + if(key1.type != key2.type) + return key1.type - key2.type; + + switch(key1.type) { + case TERMKEY_TYPE_UNICODE: + if(key1.code.codepoint != key2.code.codepoint) + return key1.code.codepoint - key2.code.codepoint; + break; + case TERMKEY_TYPE_KEYSYM: + if(key1.code.sym != key2.code.sym) + return key1.code.sym - key2.code.sym; + break; + case TERMKEY_TYPE_FUNCTION: + case TERMKEY_TYPE_UNKNOWN_CSI: + if(key1.code.number != key2.code.number) + return key1.code.number - key2.code.number; + break; + case TERMKEY_TYPE_MOUSE: + { + int cmp = strncmp(key1.code.mouse, key2.code.mouse, 4); + if(cmp != 0) + return cmp; + } + break; + case TERMKEY_TYPE_POSITION: + { + int line1, col1, line2, col2; + termkey_interpret_position(tk, &key1, &line1, &col1); + termkey_interpret_position(tk, &key2, &line2, &col2); + if(line1 != line2) + return line1 - line2; + return col1 - col2; + } + break; + case TERMKEY_TYPE_DCS: + case TERMKEY_TYPE_OSC: + return key1p - key2p; + case TERMKEY_TYPE_MODEREPORT: + { + int initial1, initial2, mode1, mode2, value1, value2; + termkey_interpret_modereport(tk, &key1, &initial1, &mode1, &value1); + termkey_interpret_modereport(tk, &key2, &initial2, &mode2, &value2); + if(initial1 != initial2) + return initial1 - initial2; + if(mode1 != mode2) + return mode1 - mode2; + return value1 - value2; + } + } + + return key1.modifiers - key2.modifiers; +} diff --git a/src/termkey/termkey.h b/src/termkey/termkey.h new file mode 100644 index 0000000000..8e10fcff0c --- /dev/null +++ b/src/termkey/termkey.h @@ -0,0 +1,249 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GUARD_TERMKEY_H_ +#define GUARD_TERMKEY_H_ + +#include +#include + +#define TERMKEY_VERSION_MAJOR 0 +#define TERMKEY_VERSION_MINOR 22 + +#define TERMKEY_CHECK_VERSION \ + termkey_check_version(TERMKEY_VERSION_MAJOR, TERMKEY_VERSION_MINOR) + +typedef enum { + TERMKEY_SYM_UNKNOWN = -1, + TERMKEY_SYM_NONE = 0, + + /* Special names in C0 */ + TERMKEY_SYM_BACKSPACE, + TERMKEY_SYM_TAB, + TERMKEY_SYM_ENTER, + TERMKEY_SYM_ESCAPE, + + /* Special names in G0 */ + TERMKEY_SYM_SPACE, + TERMKEY_SYM_DEL, + + /* Special keys */ + TERMKEY_SYM_UP, + TERMKEY_SYM_DOWN, + TERMKEY_SYM_LEFT, + TERMKEY_SYM_RIGHT, + TERMKEY_SYM_BEGIN, + TERMKEY_SYM_FIND, + TERMKEY_SYM_INSERT, + TERMKEY_SYM_DELETE, + TERMKEY_SYM_SELECT, + TERMKEY_SYM_PAGEUP, + TERMKEY_SYM_PAGEDOWN, + TERMKEY_SYM_HOME, + TERMKEY_SYM_END, + + /* Special keys from terminfo */ + TERMKEY_SYM_CANCEL, + TERMKEY_SYM_CLEAR, + TERMKEY_SYM_CLOSE, + TERMKEY_SYM_COMMAND, + TERMKEY_SYM_COPY, + TERMKEY_SYM_EXIT, + TERMKEY_SYM_HELP, + TERMKEY_SYM_MARK, + TERMKEY_SYM_MESSAGE, + TERMKEY_SYM_MOVE, + TERMKEY_SYM_OPEN, + TERMKEY_SYM_OPTIONS, + TERMKEY_SYM_PRINT, + TERMKEY_SYM_REDO, + TERMKEY_SYM_REFERENCE, + TERMKEY_SYM_REFRESH, + TERMKEY_SYM_REPLACE, + TERMKEY_SYM_RESTART, + TERMKEY_SYM_RESUME, + TERMKEY_SYM_SAVE, + TERMKEY_SYM_SUSPEND, + TERMKEY_SYM_UNDO, + + /* Numeric keypad special keys */ + TERMKEY_SYM_KP0, + TERMKEY_SYM_KP1, + TERMKEY_SYM_KP2, + TERMKEY_SYM_KP3, + TERMKEY_SYM_KP4, + TERMKEY_SYM_KP5, + TERMKEY_SYM_KP6, + TERMKEY_SYM_KP7, + TERMKEY_SYM_KP8, + TERMKEY_SYM_KP9, + TERMKEY_SYM_KPENTER, + TERMKEY_SYM_KPPLUS, + TERMKEY_SYM_KPMINUS, + TERMKEY_SYM_KPMULT, + TERMKEY_SYM_KPDIV, + TERMKEY_SYM_KPCOMMA, + TERMKEY_SYM_KPPERIOD, + TERMKEY_SYM_KPEQUALS, + + /* et cetera ad nauseum */ + TERMKEY_N_SYMS +} TermKeySym; + +typedef enum { + TERMKEY_TYPE_UNICODE, + TERMKEY_TYPE_FUNCTION, + TERMKEY_TYPE_KEYSYM, + TERMKEY_TYPE_MOUSE, + TERMKEY_TYPE_POSITION, + TERMKEY_TYPE_MODEREPORT, + TERMKEY_TYPE_DCS, + TERMKEY_TYPE_OSC, + /* add other recognised types here */ + + TERMKEY_TYPE_UNKNOWN_CSI = -1 +} TermKeyType; + +typedef enum { + TERMKEY_RES_NONE, + TERMKEY_RES_KEY, + TERMKEY_RES_EOF, + TERMKEY_RES_AGAIN, + TERMKEY_RES_ERROR +} TermKeyResult; + +typedef enum { + TERMKEY_MOUSE_UNKNOWN, + TERMKEY_MOUSE_PRESS, + TERMKEY_MOUSE_DRAG, + TERMKEY_MOUSE_RELEASE +} TermKeyMouseEvent; + +enum { + TERMKEY_KEYMOD_SHIFT = 1 << 0, + TERMKEY_KEYMOD_ALT = 1 << 1, + TERMKEY_KEYMOD_CTRL = 1 << 2 +}; + +typedef struct { + TermKeyType type; + union { + long codepoint; /* TERMKEY_TYPE_UNICODE */ + int number; /* TERMKEY_TYPE_FUNCTION */ + TermKeySym sym; /* TERMKEY_TYPE_KEYSYM */ + char mouse[4]; /* TERMKEY_TYPE_MOUSE */ + /* opaque. see termkey_interpret_mouse */ + } code; + + int modifiers; + + /* Any Unicode character can be UTF-8 encoded in no more than 6 bytes, plus + * terminating NUL */ + char utf8[7]; +} TermKeyKey; + +typedef struct TermKey TermKey; + +enum { + TERMKEY_FLAG_NOINTERPRET = 1 << 0, /* Do not interpret C0//DEL codes if possible */ + TERMKEY_FLAG_CONVERTKP = 1 << 1, /* Convert KP codes to regular keypresses */ + TERMKEY_FLAG_RAW = 1 << 2, /* Input is raw bytes, not UTF-8 */ + TERMKEY_FLAG_UTF8 = 1 << 3, /* Input is definitely UTF-8 */ + TERMKEY_FLAG_NOTERMIOS = 1 << 4, /* Do not make initial termios calls on construction */ + TERMKEY_FLAG_SPACESYMBOL = 1 << 5, /* Sets TERMKEY_CANON_SPACESYMBOL */ + TERMKEY_FLAG_CTRLC = 1 << 6, /* Allow Ctrl-C to be read as normal, disabling SIGINT */ + TERMKEY_FLAG_EINTR = 1 << 7, /* Return ERROR on signal (EINTR) rather than retry */ + TERMKEY_FLAG_NOSTART = 1 << 8 /* Do not call termkey_start() in constructor */ +}; + +enum { + TERMKEY_CANON_SPACESYMBOL = 1 << 0, /* Space is symbolic rather than Unicode */ + TERMKEY_CANON_DELBS = 1 << 1 /* Del is converted to Backspace */ +}; + +void termkey_check_version(int major, int minor); + +TermKey *termkey_new(int fd, int flags); +TermKey *termkey_new_abstract(const char *term, int flags); +void termkey_free(TermKey *tk); +void termkey_destroy(TermKey *tk); + +/* Mostly-undocumented hooks for doing evil evil things */ +typedef const char *TermKey_Terminfo_Getstr_Hook(const char *name, const char *value, void *data); +void termkey_hook_terminfo_getstr(TermKey *tk, TermKey_Terminfo_Getstr_Hook *hookfn, void *data); + +int termkey_start(TermKey *tk); +int termkey_stop(TermKey *tk); +int termkey_is_started(TermKey *tk); + +int termkey_get_fd(TermKey *tk); + +int termkey_get_flags(TermKey *tk); +void termkey_set_flags(TermKey *tk, int newflags); + +int termkey_get_waittime(TermKey *tk); +void termkey_set_waittime(TermKey *tk, int msec); + +int termkey_get_canonflags(TermKey *tk); +void termkey_set_canonflags(TermKey *tk, int); + +size_t termkey_get_buffer_size(TermKey *tk); +int termkey_set_buffer_size(TermKey *tk, size_t size); + +size_t termkey_get_buffer_remaining(TermKey *tk); + +void termkey_canonicalise(TermKey *tk, TermKeyKey *key); + +TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key); +TermKeyResult termkey_getkey_force(TermKey *tk, TermKeyKey *key); +TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key); + +TermKeyResult termkey_advisereadable(TermKey *tk); + +size_t termkey_push_bytes(TermKey *tk, const char *bytes, size_t len); + +TermKeySym termkey_register_keyname(TermKey *tk, TermKeySym sym, const char *name); +const char *termkey_get_keyname(TermKey *tk, TermKeySym sym); +const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym); + +TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname); + +TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col); + +TermKeyResult termkey_interpret_position(TermKey *tk, const TermKeyKey *key, int *line, int *col); + +TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, int *initial, int *mode, int *value); + +TermKeyResult termkey_interpret_csi(TermKey *tk, const TermKeyKey *key, long args[], size_t *nargs, unsigned long *cmd); + +TermKeyResult termkey_interpret_string(TermKey *tk, const TermKeyKey *key, const char **strp); + +typedef enum { + TERMKEY_FORMAT_LONGMOD = 1 << 0, /* Shift-... instead of S-... */ + TERMKEY_FORMAT_CARETCTRL = 1 << 1, /* ^X instead of C-X */ + TERMKEY_FORMAT_ALTISMETA = 1 << 2, /* Meta- or M- instead of Alt- or A- */ + TERMKEY_FORMAT_WRAPBRACKET = 1 << 3, /* Wrap special keys in brackets like */ + TERMKEY_FORMAT_SPACEMOD = 1 << 4, /* M Foo instead of M-Foo */ + TERMKEY_FORMAT_LOWERMOD = 1 << 5, /* meta or m instead of Meta or M */ + TERMKEY_FORMAT_LOWERSPACE = 1 << 6, /* page down instead of PageDown */ + + TERMKEY_FORMAT_MOUSE_POS = 1 << 8 /* Include mouse position if relevant; @ col,line */ +} TermKeyFormat; + +/* Some useful combinations */ + +#define TERMKEY_FORMAT_VIM (TermKeyFormat)(TERMKEY_FORMAT_ALTISMETA|TERMKEY_FORMAT_WRAPBRACKET) +#define TERMKEY_FORMAT_URWID (TermKeyFormat)(TERMKEY_FORMAT_LONGMOD|TERMKEY_FORMAT_ALTISMETA| \ + TERMKEY_FORMAT_LOWERMOD|TERMKEY_FORMAT_SPACEMOD|TERMKEY_FORMAT_LOWERSPACE) + +size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, TermKeyFormat format); +const char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermKeyFormat format); + +int termkey_keycmp(TermKey *tk, const TermKeyKey *key1, const TermKeyKey *key2); + +#endif + +#ifdef __cplusplus +} +#endif -- cgit From ce2f770aaa23591f62c2c1352fece228878f48af Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 30 Nov 2023 11:54:56 -0600 Subject: fix(termkey): do not sign extend mode value --- src/termkey/driver-csi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/termkey/driver-csi.c b/src/termkey/driver-csi.c index 37b14986d0..f179e3c9fa 100644 --- a/src/termkey/driver-csi.c +++ b/src/termkey/driver-csi.c @@ -322,7 +322,7 @@ TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, i *initial = key->code.mouse[0]; if(mode) - *mode = (key->code.mouse[1] << 8) | key->code.mouse[2]; + *mode = ((uint8_t)key->code.mouse[1] << 8) | (uint8_t)key->code.mouse[2]; if(value) *value = key->code.mouse[3]; -- cgit From 5999214c242d9103cfc68fc3102af1af47e6c9fd Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 30 Nov 2023 11:55:50 -0600 Subject: fix(termkey): accept BEL (0x07) as OSC terminator --- src/termkey/driver-csi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/termkey/driver-csi.c b/src/termkey/driver-csi.c index f179e3c9fa..86b59ac203 100644 --- a/src/termkey/driver-csi.c +++ b/src/termkey/driver-csi.c @@ -653,6 +653,8 @@ static TermKeyResult peekkey_ctrlstring(TermKey *tk, TermKeyCsi *csi, size_t int size_t str_end = introlen; while(str_end < tk->buffcount) { + if(CHARAT(str_end) == 0x07) // BEL + break; if(CHARAT(str_end) == 0x9c) // ST break; if(CHARAT(str_end) == 0x1b && -- cgit From 50f5864dd245400415e56175dd866e67a67d6c8e Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 30 Nov 2023 12:18:05 -0600 Subject: fix(termkey): include IO header on Windows --- src/termkey/driver-ti.c | 2 ++ src/termkey/termkey.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/termkey/driver-ti.c b/src/termkey/driver-ti.c index 69bc3684d3..00a7066796 100644 --- a/src/termkey/driver-ti.c +++ b/src/termkey/driver-ti.c @@ -21,6 +21,8 @@ #include #ifndef _WIN32 # include +#else +# include #endif #include #include diff --git a/src/termkey/termkey.c b/src/termkey/termkey.c index a839533982..832e5a9a9e 100644 --- a/src/termkey/termkey.c +++ b/src/termkey/termkey.c @@ -7,6 +7,8 @@ # include # include # include +#else +# include #endif #include -- cgit From 09e93d7c4d33451ffe2dd2edeb7e2124b83c8078 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 1 Dec 2023 08:06:37 +0800 Subject: refactor(IWYU): create {ex_getln,rbuffer,os/fileio}_defs.h (#26338) --- src/clint.py | 3 --- src/nvim/cmdexpand.h | 3 ++- src/nvim/eval.h | 4 +-- src/nvim/event/stream.h | 2 +- src/nvim/ex_getln.h | 69 +++-------------------------------------------- src/nvim/ex_getln_defs.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/nvim/getchar.h | 6 ++--- src/nvim/os/fileio.h | 43 ++--------------------------- src/nvim/os/fileio_defs.h | 43 +++++++++++++++++++++++++++++ src/nvim/rbuffer.c | 17 +----------- src/nvim/rbuffer.h | 18 ++----------- src/nvim/rbuffer_defs.h | 45 +++++++++++++++++++++++++++++++ src/nvim/tui/input.c | 1 + src/nvim/tui/input.h | 2 +- 14 files changed, 174 insertions(+), 150 deletions(-) create mode 100644 src/nvim/ex_getln_defs.h create mode 100644 src/nvim/os/fileio_defs.h create mode 100644 src/nvim/rbuffer_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index ddd3ff7d44..2a7eb16c9a 100755 --- a/src/clint.py +++ b/src/clint.py @@ -909,7 +909,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/buffer_defs.h", "src/nvim/channel.h", "src/nvim/charset.h", - "src/nvim/cmdexpand.h", "src/nvim/decoration.h", "src/nvim/drawline.h", "src/nvim/eval.h", @@ -930,7 +929,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/event/wstream.h", "src/nvim/extmark.h", "src/nvim/garray.h", - "src/nvim/getchar.h", "src/nvim/globals.h", "src/nvim/grid.h", "src/nvim/highlight.h", @@ -945,7 +943,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/msgpack_rpc/helpers.h", "src/nvim/msgpack_rpc/unpacker.h", "src/nvim/option.h", - "src/nvim/os/fileio.h", "src/nvim/os/input.h", "src/nvim/os/pty_conpty_win.h", "src/nvim/os/pty_process_unix.h", diff --git a/src/nvim/cmdexpand.h b/src/nvim/cmdexpand.h index b0772d26a3..a45b334cfb 100644 --- a/src/nvim/cmdexpand.h +++ b/src/nvim/cmdexpand.h @@ -2,8 +2,9 @@ #include "nvim/cmdexpand_defs.h" // IWYU pragma: export #include "nvim/eval/typval_defs.h" // IWYU pragma: keep -#include "nvim/ex_getln.h" +#include "nvim/ex_getln_defs.h" // IWYU pragma: keep #include "nvim/garray_defs.h" // IWYU pragma: keep +#include "nvim/regexp_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep // Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 7306645cc3..6d225b2713 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -13,8 +13,8 @@ #include "nvim/hashtab_defs.h" #include "nvim/macros_defs.h" #include "nvim/mbyte_defs.h" // IWYU pragma: keep -#include "nvim/os/fileio.h" -#include "nvim/os/stdpaths_defs.h" +#include "nvim/os/fileio_defs.h" // IWYU pragma: keep +#include "nvim/os/stdpaths_defs.h" // IWYU pragma: keep #include "nvim/vim_defs.h" // IWYU pragma: keep #define COPYID_INC 2 diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index d02707dc45..ab694e2247 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -6,7 +6,7 @@ #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" -#include "nvim/rbuffer.h" +#include "nvim/rbuffer_defs.h" struct stream; diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h index 93bdd2299f..af08970f0b 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -1,76 +1,13 @@ #pragma once -#include +#include // IWYU pragma: keep -#include "klib/kvec.h" -#include "nvim/cmdexpand_defs.h" -#include "nvim/eval/typval_defs.h" +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep +#include "nvim/ex_getln_defs.h" // IWYU pragma: export #include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -/// Command-line colors: one chunk -/// -/// Defines a region which has the same highlighting. -typedef struct { - int start; ///< Colored chunk start. - int end; ///< Colored chunk end (exclusive, > start). - int attr; ///< Highlight attr. -} CmdlineColorChunk; - -/// Command-line colors -/// -/// Holds data about all colors. -typedef kvec_t(CmdlineColorChunk) CmdlineColors; - -/// Command-line coloring -/// -/// Holds both what are the colors and what have been colored. Latter is used to -/// suppress unnecessary calls to coloring callbacks. -typedef struct { - unsigned prompt_id; ///< ID of the prompt which was colored last. - char *cmdbuff; ///< What exactly was colored last time or NULL. - CmdlineColors colors; ///< Last colors. -} ColoredCmdline; - -/// Keeps track how much state must be sent to external ui. -typedef enum { - kCmdRedrawNone, - kCmdRedrawPos, - kCmdRedrawAll, -} CmdRedraw; - -/// Variables shared between getcmdline(), redrawcmdline() and others. -/// These need to be saved when using CTRL-R |, that's why they are in a -/// structure. -typedef struct cmdline_info CmdlineInfo; -struct cmdline_info { - char *cmdbuff; ///< pointer to command line buffer - int cmdbufflen; ///< length of cmdbuff - int cmdlen; ///< number of chars in command line - int cmdpos; ///< current cursor position - int cmdspos; ///< cursor column on screen - int cmdfirstc; ///< ':', '/', '?', '=', '>' or NUL - int cmdindent; ///< number of spaces before cmdline - char *cmdprompt; ///< message in front of cmdline - int cmdattr; ///< attributes for prompt - int overstrike; ///< Typing mode on the command line. Shared by - ///< getcmdline() and put_on_cmdline(). - expand_T *xpc; ///< struct being used for expansion, xp_pattern - ///< may point into cmdbuff - int xp_context; ///< type of expansion - char *xp_arg; ///< user-defined expansion arg - int input_fn; ///< when true Invoked for input() function - unsigned prompt_id; ///< Prompt number, used to disable coloring on errors. - Callback highlight_callback; ///< Callback used for coloring user input. - ColoredCmdline last_colors; ///< Last cmdline colors - int level; ///< current cmdline level - CmdlineInfo *prev_ccline; ///< pointer to saved cmdline state - char special_char; ///< last putcmdline char (used for redraws) - bool special_shift; ///< shift of last putcmdline char - CmdRedraw redraw_state; ///< needed redraw for external cmdline -}; - /// flags used by vim_strsave_fnameescape() enum { VSE_NONE = 0, diff --git a/src/nvim/ex_getln_defs.h b/src/nvim/ex_getln_defs.h new file mode 100644 index 0000000000..daba6cabb8 --- /dev/null +++ b/src/nvim/ex_getln_defs.h @@ -0,0 +1,68 @@ +#pragma once + +#include + +#include "klib/kvec.h" +#include "nvim/cmdexpand_defs.h" + +/// Command-line colors: one chunk +/// +/// Defines a region which has the same highlighting. +typedef struct { + int start; ///< Colored chunk start. + int end; ///< Colored chunk end (exclusive, > start). + int attr; ///< Highlight attr. +} CmdlineColorChunk; + +/// Command-line colors +/// +/// Holds data about all colors. +typedef kvec_t(CmdlineColorChunk) CmdlineColors; + +/// Command-line coloring +/// +/// Holds both what are the colors and what have been colored. Latter is used to +/// suppress unnecessary calls to coloring callbacks. +typedef struct { + unsigned prompt_id; ///< ID of the prompt which was colored last. + char *cmdbuff; ///< What exactly was colored last time or NULL. + CmdlineColors colors; ///< Last colors. +} ColoredCmdline; + +/// Keeps track how much state must be sent to external ui. +typedef enum { + kCmdRedrawNone, + kCmdRedrawPos, + kCmdRedrawAll, +} CmdRedraw; + +/// Variables shared between getcmdline(), redrawcmdline() and others. +/// These need to be saved when using CTRL-R |, that's why they are in a +/// structure. +typedef struct cmdline_info CmdlineInfo; +struct cmdline_info { + char *cmdbuff; ///< pointer to command line buffer + int cmdbufflen; ///< length of cmdbuff + int cmdlen; ///< number of chars in command line + int cmdpos; ///< current cursor position + int cmdspos; ///< cursor column on screen + int cmdfirstc; ///< ':', '/', '?', '=', '>' or NUL + int cmdindent; ///< number of spaces before cmdline + char *cmdprompt; ///< message in front of cmdline + int cmdattr; ///< attributes for prompt + int overstrike; ///< Typing mode on the command line. Shared by + ///< getcmdline() and put_on_cmdline(). + expand_T *xpc; ///< struct being used for expansion, xp_pattern + ///< may point into cmdbuff + int xp_context; ///< type of expansion + char *xp_arg; ///< user-defined expansion arg + int input_fn; ///< when true Invoked for input() function + unsigned prompt_id; ///< Prompt number, used to disable coloring on errors. + Callback highlight_callback; ///< Callback used for coloring user input. + ColoredCmdline last_colors; ///< Last cmdline colors + int level; ///< current cmdline level + CmdlineInfo *prev_ccline; ///< pointer to saved cmdline state + char special_char; ///< last putcmdline char (used for redraws) + bool special_shift; ///< shift of last putcmdline char + CmdRedraw redraw_state; ///< needed redraw for external cmdline +}; diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h index e1bc64bfee..6e41bef298 100644 --- a/src/nvim/getchar.h +++ b/src/nvim/getchar.h @@ -1,11 +1,11 @@ #pragma once -#include -#include +#include // IWYU pragma: keep +#include // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/getchar_defs.h" // IWYU pragma: export -#include "nvim/os/fileio.h" +#include "nvim/os/fileio_defs.h" #include "nvim/types_defs.h" // IWYU pragma: keep /// Argument for flush_buffers(). diff --git a/src/nvim/os/fileio.h b/src/nvim/os/fileio.h index 72e7984c8a..55f213f377 100644 --- a/src/nvim/os/fileio.h +++ b/src/nvim/os/fileio.h @@ -1,20 +1,8 @@ #pragma once -#include -#include +#include // IWYU pragma: keep -#include "nvim/func_attr.h" -#include "nvim/rbuffer.h" - -/// Structure used to read from/write to file -typedef struct { - int fd; ///< File descriptor. - int _error; ///< Error code for use with RBuffer callbacks or zero. - RBuffer *rv; ///< Read or write buffer. - bool wr; ///< True if file is in write mode. - bool eof; ///< True if end of file was encountered. - bool non_blocking; ///< True if EAGAIN should not restart syscalls. -} FileDescriptor; +#include "nvim/os/fileio_defs.h" // IWYU pragma: export /// file_open() flags typedef enum { @@ -37,33 +25,6 @@ typedef enum { kFileMkDir = 256, } FileOpenFlags; -static inline bool file_eof(const FileDescriptor *fp) - REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL; - -/// Check whether end of file was encountered -/// -/// @param[in] fp File to check. -/// -/// @return true if it was, false if it was not or read operation was never -/// performed. -static inline bool file_eof(const FileDescriptor *const fp) -{ - return fp->eof && rbuffer_size(fp->rv) == 0; -} - -static inline int file_fd(const FileDescriptor *fp) - REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL; - -/// Return the file descriptor associated with the FileDescriptor structure -/// -/// @param[in] fp File to check. -/// -/// @return File descriptor. -static inline int file_fd(const FileDescriptor *const fp) -{ - return fp->fd; -} - enum { /// Read or write buffer size /// diff --git a/src/nvim/os/fileio_defs.h b/src/nvim/os/fileio_defs.h new file mode 100644 index 0000000000..3dc8c7b22a --- /dev/null +++ b/src/nvim/os/fileio_defs.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include "nvim/func_attr.h" +#include "nvim/rbuffer_defs.h" + +/// Structure used to read from/write to file +typedef struct { + int fd; ///< File descriptor. + int _error; ///< Error code for use with RBuffer callbacks or zero. + RBuffer *rv; ///< Read or write buffer. + bool wr; ///< True if file is in write mode. + bool eof; ///< True if end of file was encountered. + bool non_blocking; ///< True if EAGAIN should not restart syscalls. +} FileDescriptor; + +static inline bool file_eof(const FileDescriptor *fp) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL; + +/// Check whether end of file was encountered +/// +/// @param[in] fp File to check. +/// +/// @return true if it was, false if it was not or read operation was never +/// performed. +static inline bool file_eof(const FileDescriptor *const fp) +{ + return fp->eof && rbuffer_size(fp->rv) == 0; +} + +static inline int file_fd(const FileDescriptor *fp) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL; + +/// Return the file descriptor associated with the FileDescriptor structure +/// +/// @param[in] fp File to check. +/// +/// @return File descriptor. +static inline int file_fd(const FileDescriptor *const fp) +{ + return fp->fd; +} diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c index aff06ee31b..d2fae5388f 100644 --- a/src/nvim/rbuffer.c +++ b/src/nvim/rbuffer.c @@ -29,27 +29,12 @@ RBuffer *rbuffer_new(size_t capacity) return rv; } -void rbuffer_free(RBuffer *buf) +void rbuffer_free(RBuffer *buf) FUNC_ATTR_NONNULL_ALL { xfree(buf->temp); xfree(buf); } -size_t rbuffer_size(RBuffer *buf) FUNC_ATTR_NONNULL_ALL -{ - return buf->size; -} - -size_t rbuffer_capacity(RBuffer *buf) FUNC_ATTR_NONNULL_ALL -{ - return (size_t)(buf->end_ptr - buf->start_ptr); -} - -size_t rbuffer_space(RBuffer *buf) FUNC_ATTR_NONNULL_ALL -{ - return rbuffer_capacity(buf) - buf->size; -} - /// Return a pointer to a raw buffer containing the first empty slot available /// for writing. The second argument is a pointer to the maximum number of /// bytes that could be written. diff --git a/src/nvim/rbuffer.h b/src/nvim/rbuffer.h index 55e9849d3d..78483b2a50 100644 --- a/src/nvim/rbuffer.h +++ b/src/nvim/rbuffer.h @@ -16,6 +16,8 @@ #include #include +#include "nvim/rbuffer_defs.h" // IWYU pragma: export + // Macros that simplify working with the read/write pointers directly by hiding // ring buffer wrap logic. Some examples: // @@ -64,22 +66,6 @@ i-- > 0 ? ((int)(c = *rbuffer_get(buf, i))) || 1 : 0; \ ) -typedef struct rbuffer RBuffer; -/// Type of function invoked during certain events: -/// - When the RBuffer switches to the full state -/// - When the RBuffer switches to the non-full state -typedef void (*rbuffer_callback)(RBuffer *buf, void *data); - -struct rbuffer { - rbuffer_callback full_cb, nonfull_cb; - void *data; - size_t size; - // helper memory used to by rbuffer_reset if required - char *temp; - char *end_ptr, *read_ptr, *write_ptr; - char start_ptr[]; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "rbuffer.h.generated.h" #endif diff --git a/src/nvim/rbuffer_defs.h b/src/nvim/rbuffer_defs.h new file mode 100644 index 0000000000..51dc349846 --- /dev/null +++ b/src/nvim/rbuffer_defs.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include "nvim/func_attr.h" + +typedef struct rbuffer RBuffer; +/// Type of function invoked during certain events: +/// - When the RBuffer switches to the full state +/// - When the RBuffer switches to the non-full state +typedef void (*rbuffer_callback)(RBuffer *buf, void *data); + +struct rbuffer { + rbuffer_callback full_cb, nonfull_cb; + void *data; + size_t size; + // helper memory used to by rbuffer_reset if required + char *temp; + char *end_ptr, *read_ptr, *write_ptr; + char start_ptr[]; +}; + +static inline size_t rbuffer_size(RBuffer *buf) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL; + +static inline size_t rbuffer_size(RBuffer *buf) +{ + return buf->size; +} + +static inline size_t rbuffer_capacity(RBuffer *buf) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL; + +static inline size_t rbuffer_capacity(RBuffer *buf) +{ + return (size_t)(buf->end_ptr - buf->start_ptr); +} + +static inline size_t rbuffer_space(RBuffer *buf) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL; + +static inline size_t rbuffer_space(RBuffer *buf) +{ + return rbuffer_capacity(buf) - buf->size; +} diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index b9e2d2c9ee..1e14f3fee9 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -13,6 +13,7 @@ #include "nvim/memory.h" #include "nvim/option_vars.h" #include "nvim/os/os.h" +#include "nvim/rbuffer.h" #include "nvim/strings.h" #include "nvim/tui/input.h" #include "nvim/tui/input_defs.h" diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index 27a0291f5b..9d276277de 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -7,7 +7,7 @@ #include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/event/time.h" -#include "nvim/rbuffer.h" +#include "nvim/rbuffer_defs.h" #include "nvim/tui/input_defs.h" // IWYU pragma: export #include "nvim/tui/tui.h" #include "nvim/types_defs.h" -- cgit From 0bbe8e7fc257bd06a857bfc762c2b1e8e84463e1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 1 Dec 2023 09:38:04 +0800 Subject: refactor(IWYU): fix includes for highlight_group.h (#26340) --- src/clint.py | 1 - src/nvim/eval/encode.h | 1 - src/nvim/event/defs.h | 3 +-- src/nvim/highlight_group.h | 5 ++--- 4 files changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 2a7eb16c9a..596e2d8a26 100755 --- a/src/clint.py +++ b/src/clint.py @@ -932,7 +932,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/globals.h", "src/nvim/grid.h", "src/nvim/highlight.h", - "src/nvim/highlight_group.h", "src/nvim/input.h", "src/nvim/keycodes.h", "src/nvim/lua/executor.h", diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h index 699956d8ac..11a0ce3932 100644 --- a/src/nvim/eval/encode.h +++ b/src/nvim/eval/encode.h @@ -5,7 +5,6 @@ #include #include -#include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" #include "nvim/garray_defs.h" diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index 571f61dfdb..11563b99b6 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -3,14 +3,13 @@ #include #include -#define EVENT_HANDLER_MAX_ARGC 10 +enum { EVENT_HANDLER_MAX_ARGC = 10, }; typedef void (*argv_callback)(void **argv); typedef struct message { argv_callback handler; void *argv[EVENT_HANDLER_MAX_ARGC]; } Event; -typedef void (*event_scheduler)(Event event, void *data); #define VA_EVENT_INIT(event, h, a) \ do { \ diff --git a/src/nvim/highlight_group.h b/src/nvim/highlight_group.h index ca7bd36271..8a4eb83827 100644 --- a/src/nvim/highlight_group.h +++ b/src/nvim/highlight_group.h @@ -1,13 +1,12 @@ #pragma once -#include "nvim/api/keysets_defs.h" +#include "nvim/api/keysets_defs.h" // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep -#include "nvim/api/private/helpers.h" #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" #include "nvim/types_defs.h" // IWYU pragma: keep -#define MAX_HL_ID 20000 // maximum value for a highlight ID. +enum { MAX_HL_ID = 20000, }; ///< maximum value for a highlight ID. typedef struct { char *name; -- cgit From 130cb4815a5c6625a938b1e93a7d60d7a38ad8dd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 1 Dec 2023 13:56:04 +0800 Subject: fix(api): use a conditional stack for nvim_cmd (#26341) --- src/nvim/ex_docmd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index bf5a3944e6..90b816bb6f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1711,6 +1711,9 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) goto end; } + cstack_T cstack = { .cs_idx = -1 }; + eap->cstack = &cstack; + // Execute the command execute_cmd0(&retv, eap, &errormsg, preview); -- cgit From 548f03c66c08d0235d62505e884e8088bfda1804 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 1 Dec 2023 15:22:22 +0800 Subject: refactor: change event_create() to a macro (#26343) A varargs functions can never be inlined, so a macro is faster. --- src/nvim/autocmd.c | 2 +- src/nvim/channel.c | 14 +++++++------- src/nvim/event/defs.h | 24 ++---------------------- src/nvim/event/loop.c | 2 +- src/nvim/event/loop.h | 6 +++--- src/nvim/event/multiqueue.c | 2 +- src/nvim/event/multiqueue.h | 4 +++- src/nvim/event/process.c | 10 +++++----- src/nvim/event/rstream.c | 8 ++------ src/nvim/event/signal.c | 2 +- src/nvim/event/socket.c | 3 +-- src/nvim/event/time.c | 4 ++-- src/nvim/lua/executor.c | 22 ++++++++++------------ src/nvim/message.c | 4 ++-- src/nvim/msgpack_rpc/channel.c | 9 ++++----- src/nvim/os/input.c | 2 +- src/nvim/tui/input.c | 2 +- src/nvim/ui.c | 2 +- 18 files changed, 48 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 044746b7be..7d635984b8 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -2564,7 +2564,7 @@ void may_trigger_vim_suspend_resume(bool suspend) pending_vimresume = kTrue; } else if (!suspend && pending_vimresume == kTrue) { pending_vimresume = kNone; - multiqueue_put(main_loop.events, vimresume_event, 0); + multiqueue_put(main_loop.events, vimresume_event, NULL); } } diff --git a/src/nvim/channel.c b/src/nvim/channel.c index e8fe80a3b6..849b63ae31 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -244,7 +244,7 @@ void channel_decref(Channel *chan) { if (!(--chan->refcount)) { // delay free, so that libuv is done with the handles - multiqueue_put(main_loop.events, free_channel_event, 1, chan); + multiqueue_put(main_loop.events, free_channel_event, chan); } } @@ -293,7 +293,7 @@ static void channel_destroy_early(Channel *chan) } // uv will keep a reference to handles until next loop tick, so delay free - multiqueue_put(main_loop.events, free_channel_event, 1, chan); + multiqueue_put(main_loop.events, free_channel_event, chan); } static void close_cb(Stream *stream, void *data) @@ -657,7 +657,7 @@ static void schedule_channel_event(Channel *chan) { if (!chan->callback_scheduled) { if (!chan->callback_busy) { - multiqueue_put(chan->events, on_channel_event, 1, chan); + multiqueue_put(chan->events, on_channel_event, chan); channel_incref(chan); } chan->callback_scheduled = true; @@ -682,7 +682,7 @@ static void on_channel_event(void **args) chan->callback_busy = false; if (chan->callback_scheduled) { // further callback was deferred to avoid recursion. - multiqueue_put(chan->events, on_channel_event, 1, chan); + multiqueue_put(chan->events, on_channel_event, chan); channel_incref(chan); } @@ -812,7 +812,7 @@ static inline void term_delayed_free(void **argv) { Channel *chan = argv[0]; if (chan->stream.proc.in.pending_reqs || chan->stream.proc.out.pending_reqs) { - multiqueue_put(chan->events, term_delayed_free, 1, chan); + multiqueue_put(chan->events, term_delayed_free, chan); return; } @@ -826,7 +826,7 @@ static void term_close(void *data) { Channel *chan = data; process_stop(&chan->stream.proc); - multiqueue_put(chan->events, term_delayed_free, 1, data); + multiqueue_put(chan->events, term_delayed_free, data); } void channel_info_changed(Channel *chan, bool new_chan) @@ -834,7 +834,7 @@ void channel_info_changed(Channel *chan, bool new_chan) event_T event = new_chan ? EVENT_CHANOPEN : EVENT_CHANINFO; if (has_event(event)) { channel_incref(chan); - multiqueue_put(main_loop.events, set_info_event, 2, chan, event); + multiqueue_put(main_loop.events, set_info_event, chan, (void *)(intptr_t)event); } } diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index 11563b99b6..56e00171e2 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -6,29 +6,9 @@ enum { EVENT_HANDLER_MAX_ARGC = 10, }; typedef void (*argv_callback)(void **argv); -typedef struct message { +typedef struct { argv_callback handler; void *argv[EVENT_HANDLER_MAX_ARGC]; } Event; -#define VA_EVENT_INIT(event, h, a) \ - do { \ - assert(a <= EVENT_HANDLER_MAX_ARGC); \ - (event)->handler = h; \ - if (a) { \ - va_list args; \ - va_start(args, a); \ - for (int i = 0; i < a; i++) { \ - (event)->argv[i] = va_arg(args, void *); \ - } \ - va_end(args); \ - } \ - } while (0) - -static inline Event event_create(argv_callback cb, int argc, ...) -{ - assert(argc <= EVENT_HANDLER_MAX_ARGC); - Event event; - VA_EVENT_INIT(&event, cb, argc); - return event; -} +#define event_create(cb, ...) ((Event){ .handler = cb, .argv = { __VA_ARGS__ } }) diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index d61666e6d4..697bdb7aa8 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -111,7 +111,7 @@ void loop_schedule_deferred(Loop *loop, Event event) { Event *eventp = xmalloc(sizeof(*eventp)); *eventp = event; - loop_schedule_fast(loop, event_create(loop_deferred_event, 2, loop, eventp)); + loop_schedule_fast(loop, event_create(loop_deferred_event, loop, eventp)); } static void loop_deferred_event(void **argv) { diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index 5665332e95..442a159631 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -44,12 +44,12 @@ typedef struct loop { bool closing; ///< Set to true if loop_close() has been called } Loop; -#define CREATE_EVENT(multiqueue, handler, argc, ...) \ +#define CREATE_EVENT(multiqueue, handler, ...) \ do { \ if (multiqueue) { \ - multiqueue_put((multiqueue), (handler), argc, __VA_ARGS__); \ + multiqueue_put((multiqueue), (handler), __VA_ARGS__); \ } else { \ - void *argv[argc] = { __VA_ARGS__ }; \ + void *argv[] = { __VA_ARGS__ }; \ (handler)(argv); \ } \ } while (0) diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 677b7e8e6a..fd6f88153b 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -260,7 +260,7 @@ Event event_create_oneshot(Event ev, int num) data->event = ev; data->fired = false; data->refcount = num; - return event_create(multiqueue_oneshot_event, 1, data); + return event_create(multiqueue_oneshot_event, data); } static void multiqueue_oneshot_event(void **argv) { diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index e01ee1e710..7de307f77e 100644 --- a/src/nvim/event/multiqueue.h +++ b/src/nvim/event/multiqueue.h @@ -9,7 +9,9 @@ typedef struct multiqueue MultiQueue; typedef void (*PutCallback)(MultiQueue *multiq, void *data); #define multiqueue_put(q, h, ...) \ - multiqueue_put_event(q, event_create(h, __VA_ARGS__)); + do { \ + multiqueue_put_event(q, event_create(h, __VA_ARGS__)); \ + } while (0) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.h.generated.h" diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index b69612337c..ac9c4973ce 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -132,7 +132,7 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL Process *proc = (*current)->data; if (proc->detach || proc->type == kProcessTypePty) { // Close handles to process without killing it. - CREATE_EVENT(loop->events, process_close_handles, 1, proc); + CREATE_EVENT(loop->events, process_close_handles, proc); } else { process_stop(proc); } @@ -300,7 +300,7 @@ static void decref(Process *proc) } assert(node); kl_shift_at(WatcherPtr, loop->children, node); - CREATE_EVENT(proc->events, process_close_event, 1, proc); + CREATE_EVENT(proc->events, process_close_event, proc); } static void process_close(Process *proc) @@ -395,7 +395,7 @@ static void process_close_handles(void **argv) static void exit_delay_cb(uv_timer_t *handle) { uv_timer_stop(&main_loop.exit_delay_timer); - multiqueue_put(main_loop.fast_events, exit_event, 1, main_loop.exit_delay_timer.data); + multiqueue_put(main_loop.fast_events, exit_event, main_loop.exit_delay_timer.data); } static void exit_event(void **argv) @@ -420,7 +420,7 @@ static void exit_event(void **argv) void exit_from_channel(int status) { - multiqueue_put(main_loop.fast_events, exit_event, 1, status); + multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status); } static void on_process_exit(Process *proc) @@ -438,7 +438,7 @@ static void on_process_exit(Process *proc) // more data directly. Instead delay the reading after the libuv loop by // queueing process_close_handles() as an event. MultiQueue *queue = proc->events ? proc->events : loop->events; - CREATE_EVENT(queue, process_close_handles, 1, proc); + CREATE_EVENT(queue, process_close_handles, proc); } static void on_process_stream_close(Stream *stream, void *data) diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 88363e86e9..130c080db5 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -200,10 +200,6 @@ static void invoke_read_cb(Stream *stream, size_t count, bool eof) // Don't let the stream be closed before the event is processed. stream->pending_reqs++; - CREATE_EVENT(stream->events, - read_event, - 3, - stream, - (void *)(uintptr_t *)count, - (void *)(uintptr_t)eof); + CREATE_EVENT(stream->events, read_event, + stream, (void *)(uintptr_t *)count, (void *)(uintptr_t)eof); } diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index 07223be987..2d6cccf53a 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -47,7 +47,7 @@ static void signal_event(void **argv) static void signal_watcher_cb(uv_signal_t *handle, int signum) { SignalWatcher *watcher = handle->data; - CREATE_EVENT(watcher->events, signal_event, 1, watcher); + CREATE_EVENT(watcher->events, signal_event, watcher); } static void close_cb(uv_handle_t *handle) diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index c90b177eb7..cde53a00e1 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -174,8 +174,7 @@ static void connection_event(void **argv) static void connection_cb(uv_stream_t *handle, int status) { SocketWatcher *watcher = handle->data; - CREATE_EVENT(watcher->events, connection_event, 2, watcher, - (void *)(uintptr_t)status); + CREATE_EVENT(watcher->events, connection_event, watcher, (void *)(uintptr_t)status); } static void close_cb(uv_handle_t *handle) diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index 0b624d9547..7206d74176 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -52,7 +52,7 @@ static void time_watcher_cb(uv_timer_t *handle) // the timer blocked and there already is an unprocessed event waiting return; } - CREATE_EVENT(watcher->events, time_event, 1, watcher); + CREATE_EVENT(watcher->events, time_event, watcher); } static void close_event(void **argv) @@ -66,6 +66,6 @@ static void close_cb(uv_handle_t *handle) { TimeWatcher *watcher = handle->data; if (watcher->close_cb) { - CREATE_EVENT(watcher->events, close_event, 1, watcher); + CREATE_EVENT(watcher->events, close_event, watcher); } } diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 06d16efb05..d63a9a1307 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -208,7 +208,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags const char *error = lua_tostring(lstate, -1); multiqueue_put(main_loop.events, nlua_luv_error_event, - 2, xstrdup(error), (intptr_t)kCallback); + xstrdup(error), (void *)(intptr_t)kCallback); lua_pop(lstate, 1); // error message retval = -status; } else { // LUA_OK @@ -266,11 +266,11 @@ static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nres const char *error = lua_tostring(lstate, -1); loop_schedule_deferred(&main_loop, - event_create(nlua_luv_error_event, 2, + event_create(nlua_luv_error_event, xstrdup(error), - is_callback - ? (intptr_t)kThreadCallback - : (intptr_t)kThread)); + (void *)(intptr_t)(is_callback + ? kThreadCallback + : kThread))); lua_pop(lstate, 1); // error message retval = -status; } else { // LUA_OK @@ -379,8 +379,7 @@ static int nlua_schedule(lua_State *const lstate) LuaRef cb = nlua_ref_global(lstate, 1); - multiqueue_put(main_loop.events, nlua_schedule_event, - 1, (void *)(ptrdiff_t)cb); + multiqueue_put(main_loop.events, nlua_schedule_event, (void *)(ptrdiff_t)cb); return 0; } @@ -1022,15 +1021,14 @@ static int nlua_print(lua_State *const lstate) if (is_thread) { loop_schedule_deferred(&main_loop, - event_create(nlua_print_event, 2, + event_create(nlua_print_event, msg_ga.ga_data, - (intptr_t)msg_ga.ga_len)); + (void *)(intptr_t)msg_ga.ga_len)); } else if (in_fast_callback) { multiqueue_put(main_loop.events, nlua_print_event, - 2, msg_ga.ga_data, (intptr_t)msg_ga.ga_len); + msg_ga.ga_data, (void *)(intptr_t)msg_ga.ga_len); } else { - nlua_print_event((void *[]){ msg_ga.ga_data, - (void *)(intptr_t)msg_ga.ga_len }); + nlua_print_event((void *[]){ msg_ga.ga_data, (void *)(intptr_t)msg_ga.ga_len }); } return 0; diff --git a/src/nvim/message.c b/src/nvim/message.c index 8d11b793dc..219532e45e 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -871,7 +871,7 @@ void msg_schedule_semsg(const char *const fmt, ...) va_end(ap); char *s = xstrdup(IObuff); - loop_schedule_deferred(&main_loop, event_create(msg_semsg_event, 1, s)); + loop_schedule_deferred(&main_loop, event_create(msg_semsg_event, s)); } static void msg_semsg_multiline_event(void **argv) @@ -889,7 +889,7 @@ void msg_schedule_semsg_multiline(const char *const fmt, ...) va_end(ap); char *s = xstrdup(IObuff); - loop_schedule_deferred(&main_loop, event_create(msg_semsg_multiline_event, 1, s)); + loop_schedule_deferred(&main_loop, event_create(msg_semsg_multiline_event, s)); } /// Like msg(), but truncate to a single line if p_shm contains 't', or when diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 50210e4936..acc21bbf7e 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -404,7 +404,7 @@ static void handle_request(Channel *channel, Unpacker *p, Array args) if (is_get_mode && !input_blocking()) { // Defer the event to a special queue used by os/input.c. #6247 - multiqueue_put(ch_before_blocking_events, request_event, 1, evdata); + multiqueue_put(ch_before_blocking_events, request_event, evdata); } else { // Invoke immediately. request_event((void **)&evdata); @@ -412,12 +412,11 @@ static void handle_request(Channel *channel, Unpacker *p, Array args) } else { bool is_resize = p->handler.fn == handle_nvim_ui_try_resize; if (is_resize) { - Event ev = event_create_oneshot(event_create(request_event, 1, evdata), - 2); + Event ev = event_create_oneshot(event_create(request_event, evdata), 2); multiqueue_put_event(channel->events, ev); multiqueue_put_event(resize_events, ev); } else { - multiqueue_put(channel->events, request_event, 1, evdata); + multiqueue_put(channel->events, request_event, evdata); DLOG("RPC: scheduled %.*s", (int)p->method_name_len, p->handler.name); } } @@ -484,7 +483,7 @@ static bool channel_write(Channel *channel, WBuffer *buffer) if (channel->streamtype == kChannelStreamInternal) { channel_incref(channel); - CREATE_EVENT(channel->events, internal_read_event, 2, channel, buffer); + CREATE_EVENT(channel->events, internal_read_event, channel, buffer); success = true; } else { Stream *in = channel_instream(channel); diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index b86c51424c..7c404aa736 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -88,7 +88,7 @@ static void create_cursorhold_event(bool events_enabled) // TODO(tarruda): Cursorhold should be implemented as a timer set during the // `state_check` callback for the states where it can be triggered. assert(!events_enabled || multiqueue_empty(main_loop.events)); - multiqueue_put(main_loop.events, cursorhold_event, 0); + multiqueue_put(main_loop.events, cursorhold_event, NULL); } static void restart_cursorhold_wait(int tb_change_cnt) diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 1e14f3fee9..c533b288c1 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -742,7 +742,7 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *da TermInput *input = data; if (eof) { - loop_schedule_fast(&main_loop, event_create(tinput_done_event, 0)); + loop_schedule_fast(&main_loop, event_create(tinput_done_event, NULL)); return; } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 07166d229e..b068847e85 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -276,7 +276,7 @@ static void ui_refresh_event(void **argv) void ui_schedule_refresh(void) { - multiqueue_put(resize_events, ui_refresh_event, 0); + multiqueue_put(resize_events, ui_refresh_event, NULL); } void ui_default_colors_set(void) -- cgit From 76a30f2bd0f4e5abe906eabcdce092931d712be3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 1 Dec 2023 16:37:09 +0800 Subject: refactor: move float_relative_str[] to nvim_win_get_config() (#26344) It's only used in one place, as it's usually conveyed as non-string. --- src/nvim/api/win_config.c | 3 +++ src/nvim/buffer_defs.h | 2 +- src/nvim/winfloat.h | 4 ---- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 825a0583ef..856fac5585 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -311,6 +311,9 @@ static Dictionary config_put_bordertext(Dictionary config, FloatConfig *fconfig, Dictionary nvim_win_get_config(Window window, Error *err) FUNC_API_SINCE(6) { + /// Keep in sync with FloatRelative in buffer_defs.h + static const char *const float_relative_str[] = { "editor", "win", "cursor", "mouse" }; + Dictionary rv = ARRAY_DICT_INIT; win_T *wp = find_window_by_handle(window, err); diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 8928eea028..b26d42385b 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -902,7 +902,7 @@ enum { kFloatAnchorSouth = 2, }; -/// Keep in sync with float_relative_str in winfloat.h +/// Keep in sync with float_relative_str[] in nvim_win_get_config() typedef enum { kFloatRelativeEditor = 0, kFloatRelativeWindow = 1, diff --git a/src/nvim/winfloat.h b/src/nvim/winfloat.h index 877a12a9e7..6e30c8da69 100644 --- a/src/nvim/winfloat.h +++ b/src/nvim/winfloat.h @@ -10,10 +10,6 @@ /// SE -> kFloatAnchorSouth | kFloatAnchorEast EXTERN const char *const float_anchor_str[] INIT( = { "NW", "NE", "SW", "SE" }); -/// Keep in sync with FloatRelative in buffer_defs.h -EXTERN const char *const float_relative_str[] -INIT( = { "editor", "win", "cursor", "mouse" }); - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "winfloat.h.generated.h" #endif -- cgit From c58b2ee58e42e81d73f44f201b1f8c4c41ba21aa Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 1 Dec 2023 17:17:55 +0100 Subject: refactor: remove SIZEOF_INT check I have not seen any indication that this is a problem tha can occur with cmake. --- src/nvim/vim_defs.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/nvim/vim_defs.h b/src/nvim/vim_defs.h index 155265ac42..b408eb2fd7 100644 --- a/src/nvim/vim_defs.h +++ b/src/nvim/vim_defs.h @@ -8,13 +8,6 @@ #include "auto/config.h" -// Check if configure correctly managed to find sizeof(int). If this failed, -// it becomes zero. This is likely a problem of not being able to run the -// test program. Other items from configure may also be wrong then! -#if (SIZEOF_INT == 0) -# error Configure did not run properly. -#endif - enum { /// length of a buffer to store a number in ASCII (64 bits binary + NUL) NUMBUFLEN = 65, -- cgit From 983defd284f5941c870d7868cdb60587a98ab348 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 1 Dec 2023 17:07:36 +0100 Subject: refactor: remove kbtree.h --- src/klib/kbtree.h | 477 ------------------------------------------------------ 1 file changed, 477 deletions(-) delete mode 100644 src/klib/kbtree.h (limited to 'src') diff --git a/src/klib/kbtree.h b/src/klib/kbtree.h deleted file mode 100644 index 99f79952d7..0000000000 --- a/src/klib/kbtree.h +++ /dev/null @@ -1,477 +0,0 @@ -/*- - * Copyright 1997-1999, 2001, John-Mark Gurney. - * 2008-2009, Attractive Chaos - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -// Gotchas -// ------- -// -// if you delete from a kbtree while iterating over it you must use -// kb_del_itr and not kb_del otherwise the iterator might point to freed memory. - -#ifndef NVIM_LIB_KBTREE_H -#define NVIM_LIB_KBTREE_H - -#include -#include -#include -#include - -#include "nvim/memory.h" - -#define KB_MAX_DEPTH 64 - -#define __KB_KEY(type, x) (x->key) -#define __KB_PTR(btr, x) (x->ptr) - -#define __KB_TREE_T(name, key_t, T) \ - typedef struct kbnode_##name##_s kbnode_##name##_t; \ - struct kbnode_##name##_s { \ - int32_t n; \ - bool is_internal; \ - key_t key[2*T - 1]; \ - kbnode_##name##_t *ptr[]; \ - }; \ - typedef struct { \ - kbnode_##name##_t *root; \ - int n_keys, n_nodes; \ - } kbtree_##name##_t; \ - typedef struct { \ - kbnode_##name##_t *x; \ - int i; \ - } kbpos_##name##_t; \ - typedef struct { \ - kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \ - } kbitr_##name##_t; \ - - -#define __kb_destroy(kbnode_t, b) do { \ - int i; \ - unsigned int max = 8; \ - kbnode_t *x, **top, **stack = 0; \ - if (b->root) { \ - top = stack = (kbnode_t **)xcalloc(max, sizeof(kbnode_t *)); \ - *top++ = (b)->root; \ - while (top != stack) { \ - x = *--top; \ - if (x->is_internal == 0) { XFREE_CLEAR(x); continue; } \ - for (i = 0; i <= x->n; ++i) \ - if (__KB_PTR(b, x)[i]) { \ - if (top - stack == (int)max) { \ - max <<= 1; \ - stack = (kbnode_t **)xrealloc(stack, max * sizeof(kbnode_t *)); \ - top = stack + (max>>1); \ - } \ - *top++ = __KB_PTR(b, x)[i]; \ - } \ - XFREE_CLEAR(x); \ - } \ - } \ - XFREE_CLEAR(stack); \ -} while (0) - -#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ - static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, \ - int *r) \ - { \ - int tr, *rr, begin = 0, end = x->n; \ - if (x->n == 0) return -1; \ - rr = r? r : &tr; \ - while (begin < end) { \ - int mid = (begin + end) >> 1; \ - if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \ - else end = mid; \ - } \ - if (begin == x->n) { *rr = 1; return x->n - 1; } \ - if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \ - return begin; \ - } - -#define __KB_GET(name, key_t, kbnode_t) \ - static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ - { \ - if (!b->root) { \ - return 0; \ - } \ - int i, r = 0; \ - kbnode_t *x = b->root; \ - while (x) { \ - i = __kb_getp_aux_##name(x, k, &r); \ - if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \ - if (x->is_internal == 0) return 0; \ - x = __KB_PTR(b, x)[i + 1]; \ - } \ - return 0; \ - } \ - static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \ - { \ - return kb_getp_##name(b, &k); \ - } - -#define __KB_INTERVAL(name, key_t, kbnode_t) \ - static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, \ - key_t **upper) \ - { \ - if (!b->root) { \ - return; \ - } \ - int i, r = 0; \ - kbnode_t *x = b->root; \ - *lower = *upper = 0; \ - while (x) { \ - i = __kb_getp_aux_##name(x, k, &r); \ - if (i >= 0 && r == 0) { \ - *lower = *upper = &__KB_KEY(key_t, x)[i]; \ - return; \ - } \ - if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \ - if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \ - if (x->is_internal == 0) return; \ - x = __KB_PTR(b, x)[i + 1]; \ - } \ - } \ - static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \ - { \ - kb_intervalp_##name(b, &k, lower, upper); \ - } - -#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \ - /* x must be an internal node */ \ - static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \ - { \ - kbnode_t *z; \ - z = (kbnode_t *)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \ - ++b->n_nodes; \ - z->is_internal = y->is_internal; \ - z->n = T - 1; \ - memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \ - if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void *) * T); \ - y->n = T - 1; \ - memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, \ - x)[i + 1], sizeof(void *) * (unsigned int)(x->n - i)); \ - __KB_PTR(b, x)[i + 1] = z; \ - memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], \ - sizeof(key_t) * (unsigned int)(x->n - i)); \ - __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \ - ++x->n; \ - } \ - static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \ - { \ - int i = x->n - 1; \ - key_t *ret; \ - if (x->is_internal == 0) { \ - i = __kb_getp_aux_##name(x, k, 0); \ - if (i != x->n - 1) \ - memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, \ - x)[i + 1], \ - (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - ret = &__KB_KEY(key_t, x)[i + 1]; \ - *ret = *k; \ - ++x->n; \ - } else { \ - i = __kb_getp_aux_##name(x, k, 0) + 1; \ - if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \ - __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \ - if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \ - } \ - ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \ - } \ - return ret; \ - } \ - static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ - { \ - if (!b->root) { \ - b->root = (kbnode_t *)xcalloc(1, ILEN); \ - ++b->n_nodes; \ - } \ - kbnode_t *r, *s; \ - ++b->n_keys; \ - r = b->root; \ - if (r->n == 2 * T - 1) { \ - ++b->n_nodes; \ - s = (kbnode_t *)xcalloc(1, ILEN); \ - b->root = s; s->is_internal = 1; s->n = 0; \ - __KB_PTR(b, s)[0] = r; \ - __kb_split_##name(b, s, 0, r); \ - r = s; \ - } \ - return __kb_putp_aux_##name(b, r, k); \ - } \ - static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \ - { \ - kb_putp_##name(b, &k); \ - } - -#define __KB_DEL(name, key_t, kbnode_t, T) \ - static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, \ - int s) \ - { \ - int yn, zn, i, r = 0; \ - kbnode_t *xp, *y, *z; \ - key_t kp; \ - if (x == 0) return *k; \ - if (s) { /* s can only be 0, 1 or 2 */ \ - r = x->is_internal == 0? 0 : s == 1? 1 : -1; \ - i = s == 1? x->n - 1 : -1; \ - } else i = __kb_getp_aux_##name(x, k, &r); \ - if (x->is_internal == 0) { \ - if (s == 2) ++i; \ - kp = __KB_KEY(key_t, x)[i]; \ - memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \ - x)[i + 1], \ - (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - --x->n; \ - return kp; \ - } \ - if (r == 0) { \ - if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \ - xp = __KB_PTR(b, x)[i]; \ - kp = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \ - return kp; \ - } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \ - xp = __KB_PTR(b, x)[i + 1]; \ - kp = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \ - return kp; \ - } else if (yn == T - 1 && zn == T - 1) { \ - y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \ - __KB_KEY(key_t, y)[y->n++] = *k; \ - memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \ - if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, \ - z), \ - (unsigned int)(z->n + 1) * sizeof(void *)); \ - y->n += z->n; \ - memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \ - x)[i + 1], \ - (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, \ - x)[i + 2], \ - (unsigned int)(x->n - i - 1) * sizeof(void *)); \ - --x->n; \ - XFREE_CLEAR(z); \ - return __kb_delp_aux_##name(b, y, k, s); \ - } \ - } \ - ++i; \ - if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \ - if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \ - memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \ - if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, \ - xp), \ - (unsigned int)(xp->n + 1) * sizeof(void *)); \ - __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \ - __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \ - if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \ - --y->n; ++xp->n; \ - } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \ - __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ - __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \ - if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \ - --y->n; \ - memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \ - if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, \ - y)[1], \ - (unsigned int)(y->n + 1) * sizeof(void *)); \ - } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \ - __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \ - memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), \ - (unsigned int)xp->n * sizeof(key_t)); \ - if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, \ - xp), \ - (unsigned int)(xp->n + 1) * sizeof(void *)); \ - y->n += xp->n; \ - memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, \ - x)[i], \ - (unsigned int)(x->n - i) * sizeof(key_t)); \ - memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, \ - x)[i + 1], (unsigned int)(x->n - i) * sizeof(void *)); \ - --x->n; \ - XFREE_CLEAR(xp); \ - xp = y; \ - } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \ - __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \ - memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), \ - (unsigned int)y->n * sizeof(key_t)); \ - if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), \ - (unsigned int)(y->n + 1) * sizeof(void *)); \ - xp->n += y->n; \ - memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, \ - x)[i + 1], \ - (unsigned int)(x->n - i - 1) * sizeof(key_t)); \ - memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, \ - x)[i + 2], \ - (unsigned int)(x->n - i - 1) * sizeof(void *)); \ - --x->n; \ - XFREE_CLEAR(y); \ - } \ - } \ - return __kb_delp_aux_##name(b, xp, k, s); \ - } \ - static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \ - { \ - kbnode_t *x; \ - key_t ret; \ - ret = __kb_delp_aux_##name(b, b->root, k, 0); \ - --b->n_keys; \ - if (b->root->n == 0 && b->root->is_internal) { \ - --b->n_nodes; \ - x = b->root; \ - b->root = __KB_PTR(b, x)[0]; \ - XFREE_CLEAR(x); \ - } \ - return ret; \ - } \ - static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \ - { \ - return kb_delp_##name(b, &k); \ - } - -#define __KB_ITR(name, key_t, kbnode_t) \ - static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - itr->p = NULL; \ - if (b->n_keys == 0) return; \ - itr->p = itr->stack; \ - itr->p->x = b->root; itr->p->i = 0; \ - while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \ - kbnode_t *x = itr->p->x; \ - ++itr->p; \ - itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \ - } \ - } \ - static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - if (itr->p == NULL) return 0; \ - for (;;) { \ - ++itr->p->i; \ - assert(itr->p->i <= 21); \ - while (itr->p->x && itr->p->i <= itr->p->x->n) { \ - itr->p[1].i = 0; \ - itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ - ++itr->p; \ - } \ - if (itr->p == itr->stack) { \ - itr->p = NULL; \ - return 0; \ - } \ - --itr->p; \ - if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \ - } \ - } \ - static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - if (itr->p == NULL) return 0; \ - for (;;) { \ - while (itr->p->x && itr->p->i >= 0) { \ - itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \ - itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \ - ++itr->p; \ - } \ - if (itr->p == itr->stack) { \ - itr->p = NULL; \ - return 0; \ - } \ - --itr->p; \ - --itr->p->i; \ - if (itr->p->x && itr->p->i >= 0) return 1; \ - } \ - } \ - static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, \ - kbitr_##name##_t *itr) \ - { \ - if (b->n_keys == 0) { \ - itr->p = NULL; \ - return 0; \ - } \ - int i, r = 0; \ - itr->p = itr->stack; \ - itr->p->x = b->root; \ - while (itr->p->x) { \ - i = __kb_getp_aux_##name(itr->p->x, k, &r); \ - itr->p->i = i; \ - if (i >= 0 && r == 0) return 1; \ - ++itr->p->i; \ - assert(itr->p->i <= 21); \ - itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \ - ++itr->p; \ - } \ - itr->p->i = 0; \ - return 0; \ - } \ - static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \ - { \ - return kb_itr_getp_##name(b, &k, itr); \ - } \ - static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \ - { \ - key_t k = kb_itr_key(itr); \ - kb_delp_##name(b, &k); \ - kb_itr_getp_##name(b, &k, itr); \ - } - -#define KBTREE_INIT(name, key_t, __cmp, T) \ - KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, \ - (sizeof(kbnode_##name##_t) + (2*T)*sizeof(void *))) - -#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \ - __KB_TREE_T(name, key_t, T) \ - __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ - __KB_GET(name, key_t, kbnode_t) \ - __KB_INTERVAL(name, key_t, kbnode_t) \ - __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \ - __KB_DEL(name, key_t, kbnode_t, T) \ - __KB_ITR(name, key_t, kbnode_t) - -#define KB_DEFAULT_SIZE 512 - -#define kbtree_t(name) kbtree_##name##_t -#define kbitr_t(name) kbitr_##name##_t -#define kb_init(b) ((b)->n_keys = (b)->n_nodes = 0, (b)->root = 0) -#define kb_destroy(name, b) __kb_destroy(kbnode_##name##_t, b) -#define kb_get(name, b, k) kb_get_##name(b, k) -#define kb_put(name, b, k) kb_put_##name(b, k) -#define kb_del(name, b, k) kb_del_##name(b, k) -#define kb_interval(name, b, k, l, u) kb_interval_##name(b, k, l, u) -#define kb_getp(name, b, k) kb_getp_##name(b, k) -#define kb_putp(name, b, k) kb_putp_##name(b, k) -#define kb_delp(name, b, k) kb_delp_##name(b, k) -#define kb_intervalp(name, b, k, l, u) kb_intervalp_##name(b, k, l, u) - -#define kb_itr_first(name, b, i) kb_itr_first_##name(b, i) -#define kb_itr_get(name, b, k, i) kb_itr_get_##name(b, k, i) -#define kb_itr_getp(name, b, k, i) kb_itr_getp_##name(b, k, i) -#define kb_itr_next(name, b, i) kb_itr_next_##name(b, i) -#define kb_itr_prev(name, b, i) kb_itr_prev_##name(b, i) -#define kb_del_itr(name, b, i) kb_del_itr_##name(b, i) -#define kb_itr_key(itr) __KB_KEY(dummy, (itr)->p->x)[(itr)->p->i] -#define kb_itr_valid(itr) ((itr)->p >= (itr)->stack) - -#define kb_size(b) ((b)->n_keys) - -#define kb_generic_cmp(a, b) (((b) < (a)) - ((a) < (b))) -#define kb_str_cmp(a, b) strcmp(a, b) - -#endif // NVIM_LIB_KBTREE_H -- cgit From f6e5366d0077e9f171651f37282cb5c47629d1b6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 07:55:44 +0800 Subject: refactor: free more reachable memory with EXITFREE (#26349) Discovered using __sanitizer_print_memory_profile(). --- src/nvim/api/ui.c | 25 ++++++++++++++++++++----- src/nvim/autocmd.c | 5 +++++ src/nvim/channel.c | 29 +++++++++++++++++++++++------ src/nvim/eval.c | 4 ++++ src/nvim/grid.c | 5 +++++ src/nvim/map_defs.h | 17 +++++++++++++---- src/nvim/marktree.c | 1 - src/nvim/memory.c | 25 +++++++++++++++++++++++++ src/nvim/msgpack_rpc/channel.c | 5 +++++ src/nvim/msgpack_rpc/helpers.c | 8 ++++++++ src/nvim/option.c | 3 +++ src/nvim/os/env.c | 11 +++++++++++ src/nvim/os/input.c | 7 +++++++ src/nvim/ui.c | 2 ++ src/nvim/ui_client.c | 9 +++++++++ src/nvim/ui_compositor.c | 9 +++++++++ 16 files changed, 149 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 7e64ce9cd1..b73c026d57 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -106,21 +106,36 @@ static void mpack_str(char **buf, const char *str) *buf += len; } +static void remote_ui_destroy(UI *ui) + FUNC_ATTR_NONNULL_ALL +{ + UIData *data = ui->data; + kv_destroy(data->call_buf); + XFREE_CLEAR(ui->term_name); + xfree(ui); +} + void remote_ui_disconnect(uint64_t channel_id) { UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id); if (!ui) { return; } - UIData *data = ui->data; - kv_destroy(data->call_buf); pmap_del(uint64_t)(&connected_uis, channel_id, NULL); ui_detach_impl(ui, channel_id); + remote_ui_destroy(ui); +} - // Destroy `ui`. - XFREE_CLEAR(ui->term_name); - xfree(ui); +#ifdef EXITFREE +void remote_ui_free_all_mem(void) +{ + UI *ui; + map_foreach_value(&connected_uis, ui, { + remote_ui_destroy(ui); + }); + map_destroy(uint64_t, &connected_uis); } +#endif /// Wait until ui has connected on stdio channel if only_stdio /// is true, otherwise any channel. diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 7d635984b8..46a08c5706 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -2573,6 +2573,11 @@ void do_autocmd_uienter(uint64_t chanid, bool attached) { static bool recursive = false; +#ifdef EXITFREE + if (entered_free_all_mem) { + return; + } +#endif if (starting == NO_SCREEN) { return; // user config hasn't been sourced yet } diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 849b63ae31..24793bcb2a 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -53,12 +53,24 @@ static uint64_t next_chan_id = CHAN_STDERR + 1; /// Teardown the module void channel_teardown(void) { - Channel *channel; + Channel *chan; + map_foreach_value(&channels, chan, { + channel_close(chan->id, kChannelPartAll, NULL); + }); +} - map_foreach_value(&channels, channel, { - channel_close(channel->id, kChannelPartAll, NULL); +#ifdef EXITFREE +void channel_free_all_mem(void) +{ + Channel *chan; + map_foreach_value(&channels, chan, { + channel_destroy(chan); }); + map_destroy(uint64_t, &channels); + + callback_free(&on_print); } +#endif /// Closes a channel /// @@ -260,9 +272,8 @@ void callback_reader_start(CallbackReader *reader, const char *type) reader->type = type; } -static void free_channel_event(void **argv) +static void channel_destroy(Channel *chan) { - Channel *chan = argv[0]; if (chan->is_rpc) { rpc_free(chan); } @@ -275,11 +286,17 @@ static void free_channel_event(void **argv) callback_reader_free(&chan->on_stderr); callback_free(&chan->on_exit); - pmap_del(uint64_t)(&channels, chan->id, NULL); multiqueue_free(chan->events); xfree(chan); } +static void free_channel_event(void **argv) +{ + Channel *chan = argv[0]; + pmap_del(uint64_t)(&channels, chan->id, NULL); + channel_destroy(chan); +} + static void channel_destroy_early(Channel *chan) { if ((chan->id != --next_chan_id)) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6786316b8e..ae34f5715f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -500,6 +500,10 @@ static void evalvars_clear(void) p->vv_list = NULL; } } + + partial_unref(vvlua_partial); + vimvars[VV_LUA].vv_partial = vvlua_partial = NULL; + hash_clear(&vimvarht); hash_init(&vimvarht); // garbage_collect() will access it hash_clear(&compat_hashtab); diff --git a/src/nvim/grid.c b/src/nvim/grid.c index 2ef89b778e..58884e7f72 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -879,15 +879,20 @@ void grid_free(ScreenGrid *grid) grid->line_offset = NULL; } +#ifdef EXITFREE /// Doesn't allow reinit, so must only be called by free_all_mem! void grid_free_all_mem(void) { grid_free(&default_grid); + grid_free(&msg_grid); + XFREE_CLEAR(msg_grid.dirty_col); xfree(linebuf_char); xfree(linebuf_attr); xfree(linebuf_vcol); xfree(linebuf_scratch); + set_destroy(glyph, &glyph_cache); } +#endif /// (Re)allocates a window grid if size changed while in ext_multigrid mode. /// Updates size, offsets and handle for the grid regardless. diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h index 147c03327a..f3c4e4ea95 100644 --- a/src/nvim/map_defs.h +++ b/src/nvim/map_defs.h @@ -172,9 +172,14 @@ MAP_DECLS(ColorKey, ColorItem) #define set_put_ref(T, set, key, key_alloc) set_put_##T(set, key, key_alloc) #define set_put_idx(T, set, key, status) mh_put_##T(set, key, status) #define set_del(T, set, key) set_del_##T(set, key) -#define set_destroy(T, set) (xfree((set)->keys), xfree((set)->h.hash)) -#define set_clear(T, set) mh_clear(&(set)->h) #define set_size(set) ((set)->h.size) +#define set_clear(T, set) mh_clear(&(set)->h) +#define set_destroy(T, set) \ + do { \ + xfree((set)->keys); \ + xfree((set)->h.hash); \ + *(set) = (Set(T)) SET_INIT; \ + } while (0) #define map_get(T, U) map_get_##T##U #define map_has(T, map, key) set_has(T, &(map)->set, key) @@ -182,9 +187,13 @@ MAP_DECLS(ColorKey, ColorItem) #define map_ref(T, U) map_ref_##T##U #define map_put_ref(T, U) map_put_ref_##T##U #define map_del(T, U) map_del_##T##U -#define map_destroy(T, map) (set_destroy(T, &(map)->set), xfree((map)->values)) -#define map_clear(T, map) set_clear(T, &(map)->set) #define map_size(map) set_size(&(map)->set) +#define map_clear(T, map) set_clear(T, &(map)->set) +#define map_destroy(T, map) \ + do { \ + set_destroy(T, &(map)->set); \ + XFREE_CLEAR((map)->values); \ + } while (0) #define pmap_get(T) map_get(T, ptr_t) #define pmap_put(T) map_put(T, ptr_t) diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index b555b3b4ae..f14da1b605 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -1117,7 +1117,6 @@ void marktree_clear(MarkTree *b) b->root = NULL; } map_destroy(uint64_t, b->id2node); - *b->id2node = (PMap(uint64_t)) MAP_INIT; b->n_keys = 0; assert(b->n_nodes == 0); } diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 35ae6afde7..52fdf9f923 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -9,9 +9,12 @@ #include #include "nvim/api/extmark.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/ui.h" #include "nvim/arglist.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_updates.h" +#include "nvim/channel.h" #include "nvim/context.h" #include "nvim/decoration_provider.h" #include "nvim/drawline.h" @@ -23,14 +26,19 @@ #include "nvim/insexpand.h" #include "nvim/lua/executor.h" #include "nvim/main.h" +#include "nvim/map_defs.h" #include "nvim/mapping.h" #include "nvim/memfile.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option_vars.h" +#include "nvim/os/input.h" #include "nvim/sign.h" #include "nvim/state_defs.h" +#include "nvim/statusline.h" #include "nvim/ui.h" +#include "nvim/ui_client.h" +#include "nvim/ui_compositor.h" #include "nvim/usercmd.h" #include "nvim/vim_defs.h" @@ -670,6 +678,7 @@ char *arena_memdupz(Arena *arena, const char *buf, size_t size) # include "nvim/grid.h" # include "nvim/mark.h" # include "nvim/msgpack_rpc/channel.h" +# include "nvim/msgpack_rpc/helpers.h" # include "nvim/ops.h" # include "nvim/option.h" # include "nvim/os/os.h" @@ -738,6 +747,7 @@ void free_all_mem(void) free_all_marks(); alist_clear(&global_alist); free_homedir(); + free_envmap(); free_users(); free_search_patterns(); free_old_sub(); @@ -792,6 +802,7 @@ void free_all_mem(void) } } + channel_free_all_mem(); eval_clear(); api_extmark_free_all_mem(); ctx_free_all(); @@ -815,8 +826,14 @@ void free_all_mem(void) buf = bufref_valid(&bufref) ? nextbuf : firstbuf; } + map_destroy(int, &buffer_handles); + map_destroy(int, &window_handles); + map_destroy(int, &tabpage_handles); + // free screenlines (can't display anything now!) grid_free_all_mem(); + stl_clear_click_defs(tab_page_click_defs, tab_page_click_defs_size); + xfree(tab_page_click_defs); clear_hl_tables(false); @@ -824,10 +841,18 @@ void free_all_mem(void) decor_free_all_mem(); drawline_free_all_mem(); + input_free_all_mem(); + + if (ui_client_channel_id) { + ui_client_free_all_mem(); + } + remote_ui_free_all_mem(); ui_free_all_mem(); + ui_comp_free_all_mem(); nlua_free_all_mem(); rpc_free_all_mem(); + msgpack_rpc_helpers_free_all_mem(); // should be last, in case earlier free functions deallocates arenas arena_free_reuse_blks(); diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index acc21bbf7e..2336853609 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -751,6 +751,7 @@ const char *get_client_info(Channel *chan, const char *key) return NULL; } +#ifdef EXITFREE void rpc_free_all_mem(void) { cstr_t key; @@ -758,4 +759,8 @@ void rpc_free_all_mem(void) xfree((void *)key); }); set_destroy(cstr_t, &event_strings); + + msgpack_sbuffer_destroy(&out_buffer); + multiqueue_free(ch_before_blocking_events); } +#endif diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index d2be321e7a..3162269df6 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -27,6 +27,14 @@ void msgpack_rpc_helpers_init(void) msgpack_sbuffer_init(&sbuffer); } +#ifdef EXITFREE +void msgpack_rpc_helpers_free_all_mem(void) +{ + msgpack_zone_destroy(&zone); + msgpack_sbuffer_destroy(&sbuffer); +} +#endif + typedef struct { const msgpack_object *mobj; Object *aobj; diff --git a/src/nvim/option.c b/src/nvim/option.c index 882722a575..7a7cda2fa0 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -583,6 +583,9 @@ void free_all_options(void) } free_operatorfunc_option(); free_tagfunc_option(); + XFREE_CLEAR(fenc_default); + XFREE_CLEAR(p_term); + XFREE_CLEAR(p_ttytype); } #endif diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index b1e680e469..6c14f3d593 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -510,6 +510,17 @@ void free_homedir(void) xfree(homedir); } +void free_envmap(void) +{ + cstr_t name; + ptr_t e; + map_foreach(&envmap, name, e, { + xfree((char *)name); + xfree(e); + }); + map_destroy(cstr_t, &envmap); +} + #endif /// Call expand_env() and store the result in an allocated string. diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 7c404aa736..69d328754b 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -74,6 +74,13 @@ void input_stop(void) stream_close(&read_stream, NULL, NULL); } +#ifdef EXITFREE +void input_free_all_mem(void) +{ + rbuffer_free(input_buffer); +} +#endif + static void cursorhold_event(void **argv) { event_T event = State & MODE_INSERT ? EVENT_CURSORHOLDI : EVENT_CURSORHOLD; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index b068847e85..cb4ebb5c3b 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -134,6 +134,8 @@ void ui_free_all_mem(void) free_ui_event_callback(event_cb); }) map_destroy(uint32_t, &ui_event_cbs); + + multiqueue_free(resize_events); } #endif diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index a7a1c5912a..eb32c16881 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -210,3 +210,12 @@ void ui_client_event_raw_line(GridLineEvent *g) tui_raw_line(tui, grid, row, startcol, endcol, clearcol, g->cur_attr, lineflags, (const schar_T *)grid_line_buf_char, grid_line_buf_attr); } + +#ifdef EXITFREE +void ui_client_free_all_mem(void) +{ + tui_free_all_mem(tui); + xfree(grid_line_buf_char); + xfree(grid_line_buf_attr); +} +#endif diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index b698e017dc..c4078d6f63 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -60,6 +60,15 @@ void ui_comp_init(void) curgrid = &default_grid; } +#ifdef EXITFREE +void ui_comp_free_all_mem(void) +{ + kv_destroy(layers); + xfree(linebuf); + xfree(attrbuf); +} +#endif + void ui_comp_syn_init(void) { dbghl_normal = syn_check_group(S_LEN("RedrawDebugNormal")); -- cgit From 387c5ba3de356ea5c5f6fe71465440abd8563d8e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 09:55:11 +0800 Subject: revert: "memory: Free buffers after freeing variables" (#26356) This reverts commit fe30d8ccef17fff23676b8670dfec86444e2cb32. The original commit intends to prevent heap-use-after-free with EXITFREE caused by changedtick_di, which is no longer a problem. Freeing buffers after freeing variables will cause heap-use-after-free with EXITFREE when a partial is used as prompt callback. --- src/nvim/drawscreen.c | 1 - src/nvim/memory.c | 38 +++++++++++++++++++------------------- 2 files changed, 19 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 1abbc0c102..fd1589f0c5 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -2643,7 +2643,6 @@ int number_width(win_T *wp) /// Set must_redraw only if not already set to a higher value. /// e.g. if must_redraw is UPD_CLEAR, type UPD_NOT_VALID will do nothing. void redraw_later(win_T *wp, int type) - FUNC_ATTR_NONNULL_ALL { if (!exiting && wp->w_redr_type < type) { wp->w_redr_type = type; diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 52fdf9f923..7036c91c9b 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -782,6 +782,25 @@ void free_all_mem(void) // Free all option values. Must come after closing windows. free_all_options(); + // Free all buffers. Reset 'autochdir' to avoid accessing things that + // were freed already. + // Must be after eval_clear to avoid it trying to access b:changedtick after + // freeing it. + p_acd = false; + for (buf = firstbuf; buf != NULL;) { + bufref_T bufref; + set_bufref(&bufref, buf); + nextbuf = buf->b_next; + + // Since options (in addition to other stuff) have been freed above we need to ensure no + // callbacks are called, so free them before closing the buffer. + buf_free_callbacks(buf); + + close_buffer(NULL, buf, DOBUF_WIPE, false, false); + // Didn't work, try next one. + buf = bufref_valid(&bufref) ? nextbuf : firstbuf; + } + // Clear registers. clear_registers(); ResetRedobuff(); @@ -807,25 +826,6 @@ void free_all_mem(void) api_extmark_free_all_mem(); ctx_free_all(); - // Free all buffers. Reset 'autochdir' to avoid accessing things that - // were freed already. - // Must be after eval_clear to avoid it trying to access b:changedtick after - // freeing it. - p_acd = false; - for (buf = firstbuf; buf != NULL;) { - bufref_T bufref; - set_bufref(&bufref, buf); - nextbuf = buf->b_next; - - // Since options (in addition to other stuff) have been freed above we need to ensure no - // callbacks are called, so free them before closing the buffer. - buf_free_callbacks(buf); - - close_buffer(NULL, buf, DOBUF_WIPE, false, false); - // Didn't work, try next one. - buf = bufref_valid(&bufref) ? nextbuf : firstbuf; - } - map_destroy(int, &buffer_handles); map_destroy(int, &window_handles); map_destroy(int, &tabpage_handles); -- cgit From 7402655132f12f4181707dfc307636a2f6a21863 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 10:00:46 +0800 Subject: vim-patch:9.0.2140: [security]: use-after-free in win-enter Problem: [security]: use-after-free in win-enter Solution: validate window pointer before calling win_enter() win_goto() may stop visual mode, if it is active. However, this may in turn trigger the ModeChanged autocommand, which could potentially free the wp pointer which was valid before now became stale and points to now freed memory. So before calling win_enter(), let's verify one more time, that the wp pointer still points to a valid window structure. Reported by @henices, thanks! https://github.com/vim/vim/commit/eec0c2b3a4cfab93dd8d4adaa60638d47a2bbc8a Co-authored-by: Christian Brabandt --- src/nvim/window.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/window.c b/src/nvim/window.c index 7728efde33..ef1ef89d95 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4470,11 +4470,12 @@ void tabpage_move(int nr) redraw_tabline = true; } -// Go to another window. -// When jumping to another buffer, stop Visual mode. Do this before -// changing windows so we can yank the selection into the '*' register. -// When jumping to another window on the same buffer, adjust its cursor -// position to keep the same Visual area. +/// Go to another window. +/// When jumping to another buffer, stop Visual mode. Do this before +/// changing windows so we can yank the selection into the '*' register. +/// (note: this may trigger ModeChanged autocommand!) +/// When jumping to another window on the same buffer, adjust its cursor +/// position to keep the same Visual area. void win_goto(win_T *wp) { win_T *owp = curwin; @@ -4485,11 +4486,17 @@ void win_goto(win_T *wp) } if (wp->w_buffer != curbuf) { + // careful: triggers ModeChanged autocommand reset_VIsual_and_resel(); } else if (VIsual_active) { wp->w_cursor = curwin->w_cursor; } + // autocommand may have made wp invalid + if (!win_valid(wp)) { + return; + } + win_enter(wp, true); // Conceal cursor line in previous window, unconceal in current window. -- cgit From 01edcd6db85ab2abffa95bc4dce6cfb8de617bca Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 10:07:13 +0800 Subject: vim-patch:9.0.2141: [security]: buffer-overflow in suggest_trie_walk Problem: [security]: buffer-overflow in suggest_trie_walk Solution: Check n before using it as index into byts array Basically, n as an index into the byts array, can point to beyond the byts array. So let's double check, that n is within the expected range after incrementing it from sp->ts_curi and bail out if it would be invalid. Reported by @henices, thanks! https://github.com/vim/vim/commit/0fb375aae608d7306b4baf9c1f906961f32e2abf Co-authored-by: Christian Brabandt --- src/nvim/spellsuggest.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index bdac5aa587..efd647a5c3 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -1941,6 +1941,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun // - Skip the byte if it's equal to the byte in the word, // accepting that byte is always better. n += sp->ts_curi++; + + // break out, if we would be accessing byts buffer out of bounds + if (byts == slang->sl_fbyts && n >= slang->sl_fbyts_len) { + got_int = true; + break; + } c = byts[n]; if (soundfold && sp->ts_twordlen == 0 && c == '*') { // Inserting a vowel at the start of a word counts less, -- cgit From 9cc346119bee505e0be3827b35c573701a307001 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 10:10:25 +0800 Subject: vim-patch:9.0.2142: [security]: stack-buffer-overflow in option callback functions Problem: [security]: stack-buffer-overflow in option callback functions Solution: pass size of errbuf down the call stack, use snprintf() instead of sprintf() We pass the error buffer down to the option callback functions, but in some parts of the code, we simply use sprintf(buf) to write into the error buffer, which can overflow. So let's pass down the length of the error buffer and use sprintf(buf, size) instead. Reported by @henices, thanks! https://github.com/vim/vim/commit/b39b240c386a5a29241415541f1c99e2e6b8ce47 Co-authored-by: Christian Brabandt --- src/nvim/option.c | 4 ++-- src/nvim/option_defs.h | 1 + src/nvim/option_vars.h | 2 ++ src/nvim/optionstr.c | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 7a7cda2fa0..ba9d1262d4 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1455,7 +1455,7 @@ int do_set(char *arg, int opt_flags) } else { char *startarg = arg; // remember for error message const char *errmsg = NULL; - char errbuf[80]; + char errbuf[ERR_BUFLEN]; do_one_set_option(opt_flags, &arg, &did_show, errbuf, sizeof(errbuf), &errmsg); @@ -3845,7 +3845,7 @@ const char *set_option_value(const char *const name, const OptVal value, int opt int opt_idx = findoption(name); if (opt_idx < 0) { - snprintf(errbuf, IOSIZE, _(e_unknown_option2), name); + snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name); return errbuf; } diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index b2e8081a08..6d0401f319 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -66,6 +66,7 @@ typedef struct { /// is parameterized, then the "os_errbuf" buffer is used to store the error /// message (when it is not NULL). char *os_errbuf; + /// length of the error buffer size_t os_errbuflen; void *os_win; diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index b0e9ff9434..66185940ca 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -938,6 +938,8 @@ enum { // Value for b_p_ul indicating the global value must be used. #define NO_LOCAL_UNDOLEVEL (-123456) +#define ERR_BUFLEN 80 + #define SB_MAX 100000 // Maximum 'scrollback' value. #define MAX_NUMBERWIDTH 20 // used for 'numberwidth' and 'statuscolumn' diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 0a7d77e817..544524dd42 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -442,7 +442,7 @@ int check_signcolumn(win_T *wp) const char *check_stl_option(char *s) { int groupdepth = 0; - static char errbuf[80]; + static char errbuf[ERR_BUFLEN]; while (*s) { // Check for valid keys after % sequences -- cgit From 9d7544ac4cd553c9b7c8b41926b7292c5ee85943 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 2 Dec 2023 10:17:43 +0800 Subject: vim-patch:9.0.2143: [security]: buffer-overflow in ex_substitute Problem: [security]: buffer-overflow in ex_substitute Solution: clear memory after allocating When allocating the new_start pointer in ex_substitute() the memory pointer points to some garbage that the following for loop in ex_cmds.c:4743 confuses and causes it to accessing the new_start pointer beyond it's size, leading to a buffer-overlow. So fix this by using alloc_clear() instead of alloc(), which will clear the memory by NUL and therefore cause the loop to terminate correctly. Reported by @henices, thanks! closes: vim/vim#13596 https://github.com/vim/vim/commit/abfa13ebe92d81aaf66669c428d767847b577453 Co-authored-by: Christian Brabandt --- src/nvim/ex_cmds.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 2c51d64972..0711d82fe5 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3144,7 +3144,7 @@ static char *sub_grow_buf(char **new_start, int *new_start_len, int needed_len) // substitution into (and some extra space to avoid // too many calls to xmalloc()/free()). *new_start_len = needed_len + 50; - *new_start = xmalloc((size_t)(*new_start_len)); + *new_start = xcalloc(1, (size_t)(*new_start_len)); **new_start = NUL; new_end = *new_start; } else { @@ -3154,8 +3154,11 @@ static char *sub_grow_buf(char **new_start, int *new_start_len, int needed_len) size_t len = strlen(*new_start); needed_len += (int)len; if (needed_len > *new_start_len) { + size_t prev_new_start_len = (size_t)(*new_start_len); *new_start_len = needed_len + 50; + size_t added_len = (size_t)(*new_start_len) - prev_new_start_len; *new_start = xrealloc(*new_start, (size_t)(*new_start_len)); + memset(*new_start + prev_new_start_len, 0, added_len); } new_end = *new_start + len; } -- cgit From 1cc358aed6fde4f537d971ad9ee207f3d4afc97a Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sat, 2 Dec 2023 11:59:54 +0100 Subject: fix(extmarks): restore old position before revalidating --- src/nvim/extmark.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index f510845ec7..0b8aea35c0 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -389,6 +389,9 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) } else if (undo_info.type == kExtmarkSavePos) { ExtmarkSavePos pos = undo_info.data.savepos; if (undo) { + if (pos.old_row >= 0) { + extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col); + } if (pos.invalidated) { MarkTreeIter itr[1] = { 0 }; MTKey mark = marktree_lookup(curbuf->b_marktree, pos.mark, itr); @@ -396,9 +399,6 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) MTPos end = marktree_get_altpos(curbuf->b_marktree, mark, itr); buf_put_decor(curbuf, mt_decor(mark), mark.pos.row, end.row < 0 ? mark.pos.row : end.row); } - if (pos.old_row >= 0) { - extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col); - } // Redo } else { if (pos.row >= 0) { -- cgit From 64a14026d76ba1798d91e15a941fcb6af7cbc5ad Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Wed, 29 Nov 2023 22:16:09 +0200 Subject: feat(highlight): update default color scheme Problem: Default color scheme is suboptimal. Solution: Start using new color scheme. Introduce new `vim` color scheme for opt-in backward compatibility. ------ Main design ideas - Be "Neovim branded". - Be minimal for 256 colors with a bit more shades for true colors. - Be accessible through high enough contrast ratios. - Be suitable for dark and light backgrounds via exchange of dark and light palettes. ------ Palettes - Have dark and light variants. Implemented through exporeted `NvimDark*` and `NvimLight*` hex colors. - Palettes have 4 shades of grey for UI elements and 6 colors (red, yellow, green, cyan, blue, magenta). - Actual values are computed procedurally in Oklch color space based on a handful of hyperparameters. - Each color has a 256 colors variant with perceptually closest color. ------ Highlight groups Use: - Grey shades for general UI according to their design. - Bold text for keywords (`Statement` highlight group). This is an important choice to increase accessibility for people with color deficiencies, as it doesn't rely on actual color. - Green for strings, `DiffAdd` (as background), `DiagnosticOk`, and some minor text UI elements. - Cyan as main syntax color, i.e. for function usage (`Function` highlight group), `DiffText`, `DiagnosticInfo`, and some minor text UI elements. - Red to generally mean high user attention, i.e. errors; in particular for `ErrorMsg`, `DiffDelete`, `DiagnosticError`. - Yellow very sparingly only with true colors to mean mild user attention, i.e. warnings. That is, `DiagnosticWarn` and `WarningMsg`. - Blue very sparingly only with true colors as `DiagnosticHint` and some additional important syntax group (like `Identifier`). - Magenta very carefully (if at all). ------ Notes - To make tests work without relatively larege updates, each one is prepended with an equivalent of the call `:colorscheme vim`. Plus some tests which spawn new Neovim instances also now use 'vim' color scheme. In some cases tests are updated to fit new default color scheme. --- src/nvim/highlight_group.c | 527 ++++++++++++++++++++++++++------------------- 1 file changed, 304 insertions(+), 223 deletions(-) (limited to 'src') diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 3953a459bc..3bd4aa4f64 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -135,263 +135,321 @@ static const char e_missing_argument_str[] // they still work when the runtime files can't be found. static const char *highlight_init_both[] = { - "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey", - "Cursor guibg=fg guifg=bg", - "lCursor guibg=fg guifg=bg", - "DiffText cterm=bold ctermbg=Red gui=bold guibg=Red", - "ErrorMsg ctermbg=DarkRed ctermfg=White guibg=Red guifg=White", - "IncSearch cterm=reverse gui=reverse", - "ModeMsg cterm=bold gui=bold", - "NonText ctermfg=Blue gui=bold guifg=Blue", - "Normal cterm=NONE gui=NONE", - "PmenuSbar ctermbg=Grey guibg=Grey", - "StatusLine cterm=reverse,bold gui=reverse,bold", - "StatusLineNC cterm=reverse gui=reverse", - "TabLineFill cterm=reverse gui=reverse", - "TabLineSel cterm=bold gui=bold", - "TermCursor cterm=reverse gui=reverse", - "WinBar cterm=bold gui=bold", - "WildMenu ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black", - "default link VertSplit Normal", - "default link WinSeparator VertSplit", - "default link WinBarNC WinBar", - "default link EndOfBuffer NonText", - "default link LineNrAbove LineNr", - "default link LineNrBelow LineNr", - "default link QuickFixLine Search", - "default link CursorLineSign SignColumn", + "Cursor guibg=fg guifg=bg", + "CursorLineNr gui=bold cterm=bold", + "QuickFixLine gui=bold cterm=bold", + "RedrawDebugNormal gui=reverse cterm=reverse", + "TabLineSel gui=bold cterm=bold", + "TermCursor gui=reverse cterm=reverse", + "Title gui=bold cterm=bold", + "Underlined gui=underline cterm=underline", + "lCursor guibg=fg guifg=bg", + + // UI + "default link CurSearch Search", + "default link CursorIM Cursor", "default link CursorLineFold FoldColumn", - "default link CurSearch Search", - "default link PmenuKind Pmenu", - "default link PmenuKindSel PmenuSel", - "default link PmenuExtra Pmenu", - "default link PmenuExtraSel PmenuSel", - "default link Substitute Search", - "default link Whitespace NonText", - "default link MsgSeparator StatusLine", - "default link NormalFloat Pmenu", - "default link FloatBorder WinSeparator", - "default link FloatTitle Title", - "default link FloatFooter Title", - "default FloatShadow blend=80 guibg=Black", - "default FloatShadowThrough blend=100 guibg=Black", - "RedrawDebugNormal cterm=reverse gui=reverse", - "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 CursorLineSign SignColumn", + "default link EndOfBuffer NonText", + "default link FloatBorder NormalFloat", + "default link FloatFooter Title", + "default link FloatTitle Title", + "default link FoldColumn SignColumn", + "default link IncSearch Search", + "default link LineNrAbove LineNr", + "default link LineNrBelow LineNr", + "default link MsgSeparator StatusLine", + "default link MsgArea NONE", + "default link NormalNC NONE", + "default link PmenuExtra Pmenu", + "default link PmenuExtraSel PmenuSel", + "default link PmenuKind Pmenu", + "default link PmenuKindSel PmenuSel", + "default link PmenuSbar Pmenu", + "default link Substitute Search", + "default link TabLineFill TabLine", + "default link TermCursorNC NONE", + "default link VertSplit WinSeparator", + "default link VisualNOS Visual", + "default link Whitespace NonText", + "default link WildMenu PmenuSel", + "default link WinBar StatusLine", + "default link WinBarNC StatusLineNC", + "default link WinSeparator Normal", + + // Syntax + "default link Character Constant", + "default link Number Constant", + "default link Boolean Constant", + "default link Float Number", + "default link Conditional Statement", + "default link Repeat Statement", + "default link Label 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 SpecialComment Special", - "default link Debug Special", - "default DiagnosticError ctermfg=1 guifg=Red", - "default DiagnosticWarn ctermfg=3 guifg=Orange", - "default DiagnosticInfo ctermfg=4 guifg=LightBlue", - "default DiagnosticHint ctermfg=7 guifg=LightGrey", - "default DiagnosticOk ctermfg=10 guifg=LightGreen", - "default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red", - "default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange", - "default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue", - "default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey", - "default DiagnosticUnderlineOk cterm=underline gui=underline guisp=LightGreen", - "default link DiagnosticVirtualTextError DiagnosticError", - "default link DiagnosticVirtualTextWarn DiagnosticWarn", - "default link DiagnosticVirtualTextInfo DiagnosticInfo", - "default link DiagnosticVirtualTextHint DiagnosticHint", - "default link DiagnosticVirtualTextOk DiagnosticOk", - "default link DiagnosticFloatingError DiagnosticError", - "default link DiagnosticFloatingWarn DiagnosticWarn", - "default link DiagnosticFloatingInfo DiagnosticInfo", - "default link DiagnosticFloatingHint DiagnosticHint", - "default link DiagnosticFloatingOk DiagnosticOk", - "default link DiagnosticSignError DiagnosticError", - "default link DiagnosticSignWarn DiagnosticWarn", - "default link DiagnosticSignInfo DiagnosticInfo", - "default link DiagnosticSignHint DiagnosticHint", - "default link DiagnosticSignOk DiagnosticOk", - "default DiagnosticDeprecated cterm=strikethrough gui=strikethrough guisp=Red", - "default link DiagnosticUnnecessary Comment", - "default link LspInlayHint NonText", + "default link Debug Special", + "default link Ignore Normal", + "default link LspInlayHint NonText", "default link SnippetTabstop Visual", + // Diagnostic + "default link DiagnosticVirtualTextError DiagnosticError", + "default link DiagnosticVirtualTextWarn DiagnosticWarn", + "default link DiagnosticVirtualTextInfo DiagnosticInfo", + "default link DiagnosticVirtualTextHint DiagnosticHint", + "default link DiagnosticVirtualTextOk DiagnosticOk", + "default link DiagnosticSignError DiagnosticError", + "default link DiagnosticSignWarn DiagnosticWarn", + "default link DiagnosticSignInfo DiagnosticInfo", + "default link DiagnosticSignHint DiagnosticHint", + "default link DiagnosticSignOk DiagnosticOk", + "default link DiagnosticUnnecessary Comment", + // Text - "default link @text.literal Comment", + "default link @text.literal Comment", "default link @text.reference Identifier", - "default link @text.title Title", - "default link @text.uri Underlined", + "default link @text.title Title", + "default link @text.uri Underlined", "default link @text.underline Underlined", - "default link @text.todo Todo", + "default link @text.todo Todo", // Miscs - "default link @comment Comment", + "default link @comment Comment", "default link @punctuation Delimiter", // Constants - "default link @constant Constant", - "default link @constant.builtin Special", - "default link @constant.macro Define", - "default link @define Define", - "default link @macro Macro", - "default link @string String", - "default link @string.escape SpecialChar", - "default link @string.special SpecialChar", - "default link @character Character", + "default link @constant Constant", + "default link @constant.builtin Special", + "default link @constant.macro Define", + "default link @define Define", + "default link @macro Macro", + "default link @string String", + "default link @string.escape SpecialChar", + "default link @string.special SpecialChar", + "default link @character Character", "default link @character.special SpecialChar", - "default link @number Number", - "default link @boolean Boolean", - "default link @float Float", + "default link @number Number", + "default link @boolean Boolean", + "default link @float Float", // Functions - "default link @function Function", + "default link @function Function", "default link @function.builtin Special", - "default link @function.macro Macro", - "default link @parameter Identifier", - "default link @method Function", - "default link @field Identifier", - "default link @property Identifier", - "default link @constructor Special", + "default link @function.macro Macro", + "default link @parameter Identifier", + "default link @method Function", + "default link @field Identifier", + "default link @property Identifier", + "default link @constructor Special", // Keywords "default link @conditional Conditional", - "default link @repeat Repeat", - "default link @label Label", - "default link @operator Operator", - "default link @keyword Keyword", - "default link @exception Exception", - - "default link @variable Identifier", - "default link @type Type", + "default link @repeat Repeat", + "default link @label Label", + "default link @operator Operator", + "default link @keyword Keyword", + "default link @exception Exception", + + "default link @variable NONE", // don't highlight to reduce visual overload + "default link @type Type", "default link @type.definition Typedef", - "default link @storageclass StorageClass", - "default link @namespace Identifier", - "default link @include Include", - "default link @preproc PreProc", - "default link @debug Debug", - "default link @tag Tag", + "default link @storageclass StorageClass", + "default link @namespace Identifier", + "default link @include Include", + "default link @preproc PreProc", + "default link @debug Debug", + "default link @tag Tag", // LSP semantic tokens - "default link @lsp.type.class Structure", - "default link @lsp.type.comment Comment", - "default link @lsp.type.decorator Function", - "default link @lsp.type.enum Structure", - "default link @lsp.type.enumMember Constant", - "default link @lsp.type.function Function", - "default link @lsp.type.interface Structure", - "default link @lsp.type.macro Macro", - "default link @lsp.type.method Function", - "default link @lsp.type.namespace Structure", - "default link @lsp.type.parameter Identifier", - "default link @lsp.type.property Identifier", - "default link @lsp.type.struct Structure", - "default link @lsp.type.type Type", + "default link @lsp.type.class Structure", + "default link @lsp.type.comment Comment", + "default link @lsp.type.decorator Function", + "default link @lsp.type.enum Structure", + "default link @lsp.type.enumMember Constant", + "default link @lsp.type.function Function", + "default link @lsp.type.interface Structure", + "default link @lsp.type.macro Macro", + "default link @lsp.type.method Function", + "default link @lsp.type.namespace Structure", + "default link @lsp.type.parameter Identifier", + "default link @lsp.type.property Identifier", + "default link @lsp.type.struct Structure", + "default link @lsp.type.type Type", "default link @lsp.type.typeParameter TypeDef", - "default link @lsp.type.variable Identifier", + "default link @lsp.type.variable NONE", // don't highlight to reduce visual overload NULL }; // Default colors only used with a light background. static const char *highlight_init_light[] = { - "ColorColumn ctermbg=LightRed guibg=LightRed", - "CursorColumn ctermbg=LightGrey guibg=Grey90", - "CursorLine cterm=underline guibg=Grey90", - "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", - "Directory ctermfg=DarkBlue guifg=Blue", - "FoldColumn ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue", - "Folded ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue", - "LineNr ctermfg=Brown guifg=Brown", - "MatchParen ctermbg=Cyan guibg=Cyan", - "MoreMsg ctermfg=DarkGreen gui=bold guifg=SeaGreen", - "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta", - "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey", - "PmenuThumb ctermbg=Black guibg=Black", - "Question ctermfg=DarkGreen gui=bold guifg=SeaGreen", - "Search ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE", - "SignColumn ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue", - "SpecialKey ctermfg=DarkBlue guifg=Blue", - "SpellBad ctermbg=LightRed guisp=Red gui=undercurl", - "SpellCap ctermbg=LightBlue guisp=Blue gui=undercurl", - "SpellLocal ctermbg=Cyan guisp=DarkCyan gui=undercurl", - "SpellRare ctermbg=LightMagenta guisp=Magenta gui=undercurl", - "TabLine cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey", - "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", + "Normal guifg=NvimDarkGrey2 ctermfg=234 guibg=NvimLightGrey2 ctermbg=253", + + // UI + "ColorColumn guibg=NvimLightGrey4 ctermbg=247", + "Conceal guifg=NvimLightGrey4 ctermfg=247", + "CursorColumn guibg=NvimLightGrey3 ctermbg=251", + "CursorLine guibg=NvimLightGrey3 ctermbg=251", + "DiffAdd guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightGreen ctermbg=158", + "DiffChange guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightGrey4 ctermbg=247", + "DiffDelete guifg=NvimDarkRed ctermfg=52 gui=bold cterm=bold", + "DiffText guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightCyan ctermbg=123", + "Directory guifg=NvimDarkCyan ctermfg=30", + "ErrorMsg guifg=NvimDarkRed ctermfg=52", + "FloatShadow guibg=NvimLightGrey1 ctermbg=255 blend=80", + "FloatShadowThrough guibg=NvimLightGrey1 ctermbg=255 blend=100", + "Folded guifg=NvimDarkGrey4 ctermfg=239 guibg=NvimLightGrey3 ctermbg=251", + "LineNr guifg=NvimLightGrey4 ctermfg=247", + "MatchParen guibg=NvimLightGrey4 ctermbg=247 gui=bold cterm=bold", + "ModeMsg guifg=NvimDarkGreen ctermfg=22", + "MoreMsg guifg=NvimDarkCyan ctermfg=30", + "NonText guifg=NvimLightGrey4 ctermfg=247", + "NormalFloat guifg=NvimDarkGrey2 ctermfg=234 guibg=NvimLightGrey1 ctermbg=255", + "Pmenu guifg=NvimDarkGrey2 ctermfg=234 guibg=NvimLightGrey3 ctermbg=251", + "PmenuSel guifg=NvimLightGrey3 ctermfg=251 guibg=NvimDarkGrey2 ctermbg=234 blend=0", + "PmenuThumb guibg=NvimLightGrey4 ctermbg=247", + "Question guifg=NvimDarkCyan ctermfg=30", + "RedrawDebugClear guibg=NvimLightCyan ctermbg=123", + "RedrawDebugComposed guibg=NvimLightGreen ctermbg=158", + "RedrawDebugRecompose guibg=NvimLightRed ctermbg=217", + "Search guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightYellow ctermbg=222", + "SignColumn guifg=NvimLightGrey4 ctermfg=247", + "SpecialKey guifg=NvimLightGrey4 ctermfg=247", + "SpellBad guisp=NvimDarkRed gui=undercurl cterm=undercurl", + "SpellCap guisp=NvimDarkYellow gui=undercurl cterm=undercurl", + "SpellLocal guisp=NvimDarkGreen gui=undercurl cterm=undercurl", + "SpellRare guisp=NvimDarkCyan gui=undercurl cterm=undercurl", + "StatusLine guifg=NvimDarkGrey3 ctermfg=236 guibg=NvimLightGrey1 ctermbg=255", + "StatusLineNC guifg=NvimDarkGrey4 ctermfg=239 guibg=NvimLightGrey1 ctermbg=255", + "TabLine guifg=NvimDarkGrey3 ctermfg=236 guibg=NvimLightGrey1 ctermbg=255", + "Visual guibg=NvimLightGrey4 ctermbg=247", + "WarningMsg guifg=NvimDarkYellow ctermfg=52", // In 256 colors fall back to red + + // Syntax + "Comment guifg=NvimDarkGrey4 ctermfg=239", + "Constant guifg=NvimDarkGrey2 ctermfg=234", + "String guifg=NvimDarkGreen ctermfg=22", + "Identifier guifg=NvimDarkBlue ctermfg=NONE", // No fallback in 256 colors to reduce noise + "Function guifg=NvimDarkCyan ctermfg=30", + "Statement guifg=NvimDarkGrey2 ctermfg=234 gui=bold cterm=bold", + "Operator guifg=NvimDarkGrey2 ctermfg=234", + "PreProc guifg=NvimDarkGrey2 ctermfg=234", + "Type guifg=NvimDarkGrey2 ctermfg=234", + "Special guifg=NvimDarkGrey2 ctermfg=234", + "Delimiter guifg=NvimDarkGrey2 ctermfg=234", + "Error guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightRed ctermbg=217", + "Todo guifg=NvimDarkGrey1 ctermfg=232 gui=bold cterm=bold", + + // Diagnostic + "DiagnosticError guifg=NvimDarkRed ctermfg=52", + "DiagnosticWarn guifg=NvimDarkYellow ctermfg=52", // In 256 colors fall back to red + "DiagnosticInfo guifg=NvimDarkCyan ctermfg=30", + "DiagnosticHint guifg=NvimDarkBlue ctermfg=30", // In 256 colors fall back to cyan + "DiagnosticOk guifg=NvimDarkGreen ctermfg=22", + "DiagnosticUnderlineError guisp=NvimDarkRed gui=underline cterm=underline", + "DiagnosticUnderlineWarn guisp=NvimDarkYellow gui=underline cterm=underline", + "DiagnosticUnderlineInfo guisp=NvimDarkCyan gui=underline cterm=underline", + "DiagnosticUnderlineHint guisp=NvimDarkBlue gui=underline cterm=underline", // In 256 colors fall back to cyan + "DiagnosticUnderlineOk guisp=NvimDarkGreen gui=underline cterm=underline", + "DiagnosticFloatingError guifg=NvimDarkRed ctermfg=52 guibg=NvimLightGrey1 ctermbg=255", + // In 256 colors fall back to red + "DiagnosticFloatingWarn guifg=NvimDarkYellow ctermfg=52 guibg=NvimLightGrey1 ctermbg=255", + "DiagnosticFloatingInfo guifg=NvimDarkCyan ctermfg=30 guibg=NvimLightGrey1 ctermbg=255", + // In 256 colors fall back to cyan + "DiagnosticFloatingHint guifg=NvimDarkBlue ctermfg=30 guibg=NvimLightGrey1 ctermbg=255", + "DiagnosticFloatingOk guifg=NvimDarkGreen ctermfg=22 guibg=NvimLightGrey1 ctermbg=255", + "DiagnosticDeprecated guisp=NvimDarkRed gui=strikethrough cterm=strikethrough", NULL }; // Default colors only used with a dark background. static const char *highlight_init_dark[] = { - "ColorColumn ctermbg=DarkRed guibg=DarkRed", - "CursorColumn ctermbg=DarkGrey guibg=Grey40", - "CursorLine cterm=underline guibg=Grey40", - "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", - "Directory ctermfg=LightCyan guifg=Cyan", - "FoldColumn ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan", - "Folded ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan", - "LineNr ctermfg=Yellow guifg=Yellow", - "MatchParen ctermbg=DarkCyan guibg=DarkCyan", - "MoreMsg ctermfg=LightGreen gui=bold guifg=SeaGreen", - "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta", - "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey", - "PmenuThumb ctermbg=White guibg=White", - "Question ctermfg=LightGreen gui=bold guifg=Green", - "Search ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black", - "SignColumn ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan", - "SpecialKey ctermfg=LightBlue guifg=Cyan", - "SpellBad ctermbg=Red guisp=Red gui=undercurl", - "SpellCap ctermbg=Blue guisp=Blue gui=undercurl", - "SpellLocal ctermbg=Cyan guisp=Cyan gui=undercurl", - "SpellRare ctermbg=Magenta guisp=Magenta gui=undercurl", - "TabLine cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey", - "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", + "Normal guifg=NvimLightGrey2 ctermfg=253 guibg=NvimDarkGrey2 ctermbg=234", + + // UI + "ColorColumn guibg=NvimDarkGrey4 ctermbg=239", + "Conceal guifg=NvimDarkGrey4 ctermfg=239", + "CursorColumn guibg=NvimDarkGrey3 ctermbg=236", + "CursorLine guibg=NvimDarkGrey3 ctermbg=236", + "DiffAdd guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkGreen ctermbg=22", + "DiffChange guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkGrey4 ctermbg=239", + "DiffDelete guifg=NvimLightRed ctermfg=217 gui=bold cterm=bold", + "DiffText guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkCyan ctermbg=30", + "Directory guifg=NvimLightCyan ctermfg=123", + "ErrorMsg guifg=NvimLightRed ctermfg=217", + "FloatShadow guibg=NvimDarkGrey1 ctermbg=232 blend=80", + "FloatShadowThrough guibg=NvimDarkGrey1 ctermbg=232 blend=100", + "Folded guifg=NvimLightGrey4 ctermfg=247 guibg=NvimDarkGrey3 ctermbg=236", + "LineNr guifg=NvimDarkGrey4 ctermfg=239", + "MatchParen guibg=NvimDarkGrey4 ctermbg=239 gui=bold cterm=bold", + "ModeMsg guifg=NvimLightGreen ctermfg=158", + "MoreMsg guifg=NvimLightCyan ctermfg=123", + "NonText guifg=NvimDarkGrey4 ctermfg=239", + "NormalFloat guifg=NvimLightGrey2 ctermfg=253 guibg=NvimDarkGrey1 ctermbg=232", + "Pmenu guifg=NvimLightGrey2 ctermfg=253 guibg=NvimDarkGrey3 ctermbg=236", + "PmenuSel guifg=NvimDarkGrey3 ctermfg=236 guibg=NvimLightGrey2 ctermbg=253 blend=0", + "PmenuThumb guibg=NvimDarkGrey4 ctermbg=239", + "Question guifg=NvimLightCyan ctermfg=123", + "RedrawDebugClear guibg=NvimDarkCyan ctermbg=30", + "RedrawDebugComposed guibg=NvimDarkGreen ctermbg=22", + "RedrawDebugRecompose guibg=NvimDarkRed ctermbg=52", + "Search guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkYellow ctermbg=58", + "SignColumn guifg=NvimDarkGrey4 ctermfg=239", + "SpecialKey guifg=NvimDarkGrey4 ctermfg=239", + "SpellBad guisp=NvimLightRed gui=undercurl cterm=undercurl", + "SpellCap guisp=NvimLightYellow gui=undercurl cterm=undercurl", + "SpellLocal guisp=NvimLightGreen gui=undercurl cterm=undercurl", + "SpellRare guisp=NvimLightCyan gui=undercurl cterm=undercurl", + "StatusLine guifg=NvimLightGrey3 ctermfg=251 guibg=NvimDarkGrey1 ctermbg=232", + "StatusLineNC guifg=NvimLightGrey4 ctermfg=247 guibg=NvimDarkGrey1 ctermbg=232", + "TabLine guifg=NvimLightGrey3 ctermfg=251 guibg=NvimDarkGrey1 ctermbg=232", + "Visual guibg=NvimDarkGrey4 ctermbg=239", + "WarningMsg guifg=NvimLightYellow ctermfg=217", // In 256 colors fall back to red + + // Syntax + "Comment guifg=NvimLightGrey4 ctermfg=247", + "Constant guifg=NvimLightGrey2 ctermfg=253", + "String guifg=NvimLightGreen ctermfg=158", + "Identifier guifg=NvimLightBlue ctermfg=NONE", // No fallback in 256 colors to reduce noise + "Function guifg=NvimLightCyan ctermfg=123", + "Statement guifg=NvimLightGrey2 ctermfg=253 gui=bold cterm=bold", + "Operator guifg=NvimLightGrey2 ctermfg=253", + "PreProc guifg=NvimLightGrey2 ctermfg=253", + "Type guifg=NvimLightGrey2 ctermfg=253", + "Special guifg=NvimLightGrey2 ctermfg=253", + "Delimiter guifg=NvimLightGrey2 ctermfg=253", + "Error guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkRed ctermbg=52", + "Todo guifg=NvimLightGrey1 ctermfg=255 gui=bold cterm=bold", + + // Diagnostic + "DiagnosticError guifg=NvimLightRed ctermfg=217", + "DiagnosticWarn guifg=NvimLightYellow ctermfg=217", // In 256 colors fall back to red + "DiagnosticInfo guifg=NvimLightCyan ctermfg=123", + "DiagnosticHint guifg=NvimLightBlue ctermfg=123", // In 256 colors fall back to cyan + "DiagnosticOk guifg=NvimLightGreen ctermfg=158", + "DiagnosticUnderlineError guisp=NvimLightRed gui=underline cterm=underline", + "DiagnosticUnderlineWarn guisp=NvimLightYellow gui=underline cterm=underline", // In 256 colors fall back to red + "DiagnosticUnderlineInfo guisp=NvimLightCyan gui=underline cterm=underline", + "DiagnosticUnderlineHint guisp=NvimLightBlue gui=underline cterm=underline", + "DiagnosticUnderlineOk guisp=NvimLightGreen gui=underline cterm=underline", + "DiagnosticFloatingError guifg=NvimLightRed ctermfg=217 guibg=NvimDarkGrey1 ctermbg=232", + // In 256 colors fall back to red + "DiagnosticFloatingWarn guifg=NvimLightYellow ctermfg=217 guibg=NvimDarkGrey1 ctermbg=232", + "DiagnosticFloatingInfo guifg=NvimLightCyan ctermfg=123 guibg=NvimDarkGrey1 ctermbg=232", + // In 256 colors fall back to cyan + "DiagnosticFloatingHint guifg=NvimLightBlue ctermfg=123 guibg=NvimDarkGrey1 ctermbg=232", + "DiagnosticFloatingOk guifg=NvimLightGreen ctermfg=158 guibg=NvimDarkGrey1 ctermbg=232", + "DiagnosticDeprecated guisp=NvimLightRed gui=strikethrough cterm=strikethrough", NULL }; @@ -2828,6 +2886,29 @@ color_name_table_T color_name_table[] = { { "NavajoWhite4", RGB_(0x8b, 0x79, 0x5e) }, { "Navy", RGB_(0x00, 0x00, 0x80) }, { "NavyBlue", RGB_(0x0, 0x0, 0x80) }, + // Default Neovim palettes. + // Dark/light palette is used for background in dark/light color scheme and + // for foreground in light/dark color scheme. + { "NvimDarkBlue", RGB_(0x00, 0x50, 0x78) }, // cterm=24 + { "NvimDarkCyan", RGB_(0x00, 0x76, 0x76) }, // cterm=30 + { "NvimDarkGreen", RGB_(0x01, 0x58, 0x25) }, // cterm=22 + { "NvimDarkGrey1", RGB_(0x0a, 0x0b, 0x10) }, // cterm=232 + { "NvimDarkGrey2", RGB_(0x1c, 0x1d, 0x23) }, // cterm=234 + { "NvimDarkGrey3", RGB_(0x2c, 0x2e, 0x33) }, // cterm=236 + { "NvimDarkGrey4", RGB_(0x4f, 0x52, 0x58) }, // cterm=239 + { "NvimDarkMagenta", RGB_(0x4c, 0x00, 0x49) }, // cterm=53 + { "NvimDarkRed", RGB_(0x5e, 0x00, 0x09) }, // cterm=52 + { "NvimDarkYellow", RGB_(0x6e, 0x56, 0x00) }, // cterm=58 + { "NvimLightBlue", RGB_(0x9f, 0xd8, 0xff) }, // cterm=153 + { "NvimLightCyan", RGB_(0x83, 0xef, 0xef) }, // cterm=123 + { "NvimLightGreen", RGB_(0xaa, 0xed, 0xb7) }, // cterm=158 + { "NvimLightGrey1", RGB_(0xeb, 0xee, 0xf5) }, // cterm=255 + { "NvimLightGrey2", RGB_(0xd7, 0xda, 0xe1) }, // cterm=253 + { "NvimLightGrey3", RGB_(0xc4, 0xc6, 0xcd) }, // cterm=251 + { "NvimLightGrey4", RGB_(0x9b, 0x9e, 0xa4) }, // cterm=247 + { "NvimLightMagenta", RGB_(0xff, 0xc3, 0xfa) }, // cterm=189 + { "NvimLightRed", RGB_(0xff, 0xbc, 0xb5) }, // cterm=217 + { "NvimLightYellow", RGB_(0xf4, 0xd8, 0x8c) }, // cterm=222 { "OldLace", RGB_(0xfd, 0xf5, 0xe6) }, { "Olive", RGB_(0x80, 0x80, 0x00) }, { "OliveDrab", RGB_(0x6b, 0x8e, 0x23) }, -- cgit From 481a3158866638946c91fab28ae5bca97ff1e814 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 2 Dec 2023 14:10:26 +0100 Subject: refactor: remove unused file ringbuf.h --- src/nvim/lib/ringbuf.h | 290 ------------------------------------------------- 1 file changed, 290 deletions(-) delete mode 100644 src/nvim/lib/ringbuf.h (limited to 'src') diff --git a/src/nvim/lib/ringbuf.h b/src/nvim/lib/ringbuf.h deleted file mode 100644 index c8abccfeb4..0000000000 --- a/src/nvim/lib/ringbuf.h +++ /dev/null @@ -1,290 +0,0 @@ -/// Macros-based ring buffer implementation. -/// -/// Supported functions: -/// -/// - new: allocates new ring buffer. -/// - dealloc: free ring buffer itself. -/// - free: free ring buffer and all its elements. -/// - push: adds element to the end of the buffer. -/// - length: get buffer length. -/// - size: size of the ring buffer. -/// - idx: get element at given index. -/// - idx_p: get pointer to the element at given index. -/// - insert: insert element at given position. -/// - remove: remove element from given position. - -#pragma once - -#include -#include -#include -#include - -#include "nvim/func_attr.h" -#include "nvim/memory.h" - -#define _RINGBUF_LENGTH(rb) \ - ((rb)->first == NULL ? 0 \ - : ((rb)->next == (rb)->first) ? (size_t)((rb)->buf_end - (rb)->buf) + 1 \ - : ((rb)->next > (rb)->first) ? (size_t)((rb)->next - (rb)->first) \ - : (size_t)((rb)->next - (rb)->buf + (rb)->buf_end - (rb)->first + 1)) - -#define _RINGBUF_NEXT(rb, var) \ - ((var) == (rb)->buf_end ? (rb)->buf : (var) + 1) -#define _RINGBUF_PREV(rb, var) \ - ((var) == (rb)->buf ? (rb)->buf_end : (var) - 1) - -/// Iterate over all ringbuf values -/// -/// @param rb Ring buffer to iterate over. -/// @param RBType Type of the ring buffer element. -/// @param varname Variable name. -#define RINGBUF_FORALL(rb, RBType, varname) \ - size_t varname##_length_fa_ = _RINGBUF_LENGTH(rb); \ - for (RBType *varname = ((rb)->first == NULL ? (rb)->next : (rb)->first); \ - varname##_length_fa_; \ - (varname = _RINGBUF_NEXT(rb, varname)), \ - varname##_length_fa_--) - -/// Iterate over all ringbuf values, from end to the beginning -/// -/// Unlike previous RINGBUF_FORALL uses already defined variable, in place of -/// defining variable in the cycle body. -/// -/// @param rb Ring buffer to iterate over. -/// @param RBType Type of the ring buffer element. -/// @param varname Variable name. -#define RINGBUF_ITER_BACK(rb, RBType, varname) \ - size_t varname##_length_ib_ = _RINGBUF_LENGTH(rb); \ - for (varname = ((rb)->next == (rb)->buf ? (rb)->buf_end : (rb)->next - 1); \ - varname##_length_ib_; \ - (varname = _RINGBUF_PREV(rb, varname)), \ - varname##_length_ib_--) - -/// Define a ring buffer structure -/// -/// @param TypeName Ring buffer type name. Actual type name will be -/// `{TypeName}RingBuffer`. -/// @param RBType Type of the single ring buffer element. -#define RINGBUF_TYPEDEF(TypeName, RBType) \ - typedef struct { \ - RBType *buf; \ - RBType *next; \ - RBType *first; \ - RBType *buf_end; \ - } TypeName##RingBuffer; - -/// Dummy item free macros, for use in RINGBUF_INIT -/// -/// This macros actually does nothing. -/// -/// @param[in] item Item to be freed. -#define RINGBUF_DUMMY_FREE(item) - -/// Static ring buffer -/// -/// @warning Ring buffers created with this macros must neither be freed nor -/// deallocated. -/// -/// @param scope Ring buffer scope. -/// @param TypeName Ring buffer type name. -/// @param RBType Type of the single ring buffer element. -/// @param varname Variable name. -/// @param rbsize Ring buffer size. -#define RINGBUF_STATIC(scope, TypeName, RBType, varname, rbsize) \ - static RBType _##varname##_buf[rbsize]; \ - scope TypeName##RingBuffer varname = { \ - .buf = _##varname##_buf, \ - .next = _##varname##_buf, \ - .first = NULL, \ - .buf_end = _##varname##_buf + rbsize - 1, \ - }; - -/// Initialize a new ring buffer -/// -/// @param TypeName Ring buffer type name. Actual type name will be -/// `{TypeName}RingBuffer`. -/// @param funcprefix Prefix for all ring buffer functions. Function name will -/// look like `{funcprefix}_rb_{function_name}`. -/// @param RBType Type of the single ring buffer element. -/// @param rbfree Function used to free ring buffer element. May be -/// a macros like `#define RBFREE(item)` (to skip freeing). -/// -/// Intended function signature: `void *rbfree(RBType *)`; -#define RINGBUF_INIT(TypeName, funcprefix, RBType, rbfree) \ - static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ - REAL_FATTR_WARN_UNUSED_RESULT; \ - static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ - { \ - assert(size != 0); \ - RBType *buf = xmalloc(size * sizeof(RBType)); \ - return (TypeName##RingBuffer) { \ - .buf = buf, \ - .next = buf, \ - .first = NULL, \ - .buf_end = buf + size - 1, \ - }; \ - } \ - static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ - REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ - { \ - if (rb == NULL) { \ - return; \ - } \ - RINGBUF_FORALL(rb, RBType, rbitem) { \ - rbfree(rbitem); \ - } \ - XFREE_CLEAR(rb->buf); \ - } \ - static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ - REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ - { \ - XFREE_CLEAR(rb->buf); \ - } \ - static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ - RBType item) \ - REAL_FATTR_NONNULL_ARG(1); \ - static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ - RBType item) \ - { \ - if (rb->next == rb->first) { \ - rbfree(rb->first); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } else if (rb->first == NULL) { \ - rb->first = rb->next; \ - } \ - *rb->next = item; \ - rb->next = _RINGBUF_NEXT(rb, rb->next); \ - } \ - static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \ - const RBType *const item_p) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \ - static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \ - const RBType *const item_p) \ - { \ - assert(rb->buf <= item_p); \ - assert(rb->buf_end >= item_p); \ - if (rb->first == NULL) { \ - return -1; \ - } else if (item_p >= rb->first) { \ - return item_p - rb->first; \ - } else { \ - return item_p - rb->buf + rb->buf_end - rb->first + 1; \ - } \ - } \ - static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ - static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \ - { \ - return (size_t)(rb->buf_end - rb->buf) + 1; \ - } \ - static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ - static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \ - { \ - return _RINGBUF_LENGTH(rb); \ - } \ - static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ - static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - { \ - assert(idx <= funcprefix##_rb_size(rb)); \ - assert(idx <= funcprefix##_rb_length(rb)); \ - if (rb->first + idx > rb->buf_end) { \ - return rb->buf + ((rb->first + idx) - (rb->buf_end + 1)); \ - } else { \ - return rb->first + idx; \ - } \ - } \ - static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \ - static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - { \ - return *funcprefix##_rb_idx_p(rb, idx); \ - } \ - static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ - const size_t idx, \ - RBType item) \ - REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ - const size_t idx, \ - RBType item) \ - { \ - assert(idx <= funcprefix##_rb_size(rb)); \ - assert(idx <= funcprefix##_rb_length(rb)); \ - const size_t length = funcprefix##_rb_length(rb); \ - if (idx == length) { \ - funcprefix##_rb_push(rb, item); \ - return; \ - } \ - RBType *const insertpos = funcprefix##_rb_idx_p(rb, idx); \ - if (insertpos == rb->next) { \ - funcprefix##_rb_push(rb, item); \ - return; \ - } \ - if (length == funcprefix##_rb_size(rb)) { \ - rbfree(rb->first); \ - } \ - if (insertpos < rb->next) { \ - memmove(insertpos + 1, insertpos, \ - (size_t)((uintptr_t)rb->next - (uintptr_t)insertpos)); \ - } else { \ - assert(insertpos > rb->first); \ - assert(rb->next <= rb->first); \ - memmove(rb->buf + 1, rb->buf, \ - (size_t)((uintptr_t)rb->next - (uintptr_t)rb->buf)); \ - *rb->buf = *rb->buf_end; \ - memmove(insertpos + 1, insertpos, \ - (size_t)((uintptr_t)(rb->buf_end + 1) - (uintptr_t)insertpos)); \ - } \ - *insertpos = item; \ - if (length == funcprefix##_rb_size(rb)) { \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } \ - rb->next = _RINGBUF_NEXT(rb, rb->next); \ - } \ - static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ - const size_t idx) \ - REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ - const size_t idx) \ - { \ - assert(idx < funcprefix##_rb_size(rb)); \ - assert(idx < funcprefix##_rb_length(rb)); \ - RBType *const rmpos = funcprefix##_rb_idx_p(rb, idx); \ - rbfree(rmpos); \ - if (rmpos == rb->next - 1) { \ - rb->next--; \ - if (rb->first == rb->next) { \ - rb->first = NULL; \ - rb->next = rb->buf; \ - } \ - } else if (rmpos == rb->first) { \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - if (rb->first == rb->next) { \ - rb->first = NULL; \ - rb->next = rb->buf; \ - } \ - } else if (rb->first < rb->next || rb->next == rb->buf) { \ - assert(rmpos > rb->first); \ - assert(rmpos <= _RINGBUF_PREV(rb, rb->next)); \ - memmove(rb->first + 1, rb->first, \ - (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } else if (rmpos < rb->next) { \ - memmove(rmpos, rmpos + 1, \ - (size_t)((uintptr_t)rb->next - (uintptr_t)rmpos)); \ - rb->next = _RINGBUF_PREV(rb, rb->next); \ - } else { \ - assert(rb->first < rb->buf_end); \ - memmove(rb->first + 1, rb->first, \ - (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } \ - } -- cgit From 5651c1ff27a1eb59d120637ba5cbd90f08a3f1d2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 4 Dec 2023 06:42:47 +0800 Subject: vim-patch:9.0.2145: wrong scrolling in insert mode with smoothscroll (#26375) Problem: Wrong scrolling in Insert mode with 'smoothscroll' at the bottom of the window. Solution: Don't use set_topline() when 'smoothscroll' is set. fixes: vim/vim#13612 closes: vim/vim#13613 https://github.com/vim/vim/commit/5b4d1fcbf06757bae32a894871b9a649c84eba7f --- src/nvim/drawscreen.c | 2 ++ src/nvim/edit.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index fd1589f0c5..85f62db774 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -2644,6 +2644,8 @@ int number_width(win_T *wp) /// e.g. if must_redraw is UPD_CLEAR, type UPD_NOT_VALID will do nothing. void redraw_later(win_T *wp, int type) { + // curwin may have been set to NULL when exiting + assert(wp != NULL || exiting); if (!exiting && wp->w_redr_type < type) { wp->w_redr_type = type; if (type >= UPD_NOT_VALID) { diff --git a/src/nvim/edit.c b/src/nvim/edit.c index dd7cd9a573..ba2885a162 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -444,8 +444,11 @@ static int insert_check(VimState *state) // is detected when the cursor column is smaller after inserting something. // Don't do this when the topline changed already, it has already been // adjusted (by insertchar() calling open_line())). + // Also don't do this when 'smoothscroll' is set, as the window should then + // be scrolled by screen lines. if (curbuf->b_mod_set && curwin->w_p_wrap + && !curwin->w_p_sms && !s->did_backspace && curwin->w_topline == s->old_topline && curwin->w_topfill == s->old_topfill) { -- cgit From 589f4761ee896cea5c8d1b1dad6655bd0b78fc2d Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 4 Dec 2023 15:49:31 +0800 Subject: refactor(completion): use an inline function to free cptext (#26380) --- src/nvim/insexpand.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index a59ba1b6d9..8791aeb10c 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -747,6 +747,16 @@ int ins_compl_add_infercase(char *str_arg, int len, bool icase, char *fname, Dir return res; } +/// free cptext +static inline void free_cptext(char *const *const cptext) +{ + if (cptext != NULL) { + for (size_t i = 0; i < CPT_COUNT; i++) { + xfree(cptext[i]); + } + } +} + /// Add a match to the list of matches /// /// @param[in] str text of the match to add @@ -784,16 +794,10 @@ static int ins_compl_add(char *const str, int len, char *const fname, char *cons } else { os_breakcheck(); } -#define FREE_CPTEXT(cptext, cptext_allocated) \ - do { \ - if ((cptext) != NULL && (cptext_allocated)) { \ - for (size_t i = 0; i < CPT_COUNT; i++) { \ - xfree((cptext)[i]); \ - } \ - } \ - } while (0) if (got_int) { - FREE_CPTEXT(cptext, cptext_allocated); + if (cptext_allocated) { + free_cptext(cptext); + } return FAIL; } if (len < 0) { @@ -807,7 +811,9 @@ static int ins_compl_add(char *const str, int len, char *const fname, char *cons if (!match_at_original_text(match) && strncmp(match->cp_str, str, (size_t)len) == 0 && ((int)strlen(match->cp_str) <= len || match->cp_str[len] == NUL)) { - FREE_CPTEXT(cptext, cptext_allocated); + if (cptext_allocated) { + free_cptext(cptext); + } return NOTDONE; } match = match->cp_next; @@ -1552,9 +1558,7 @@ static void ins_compl_free(void) if (match->cp_flags & CP_FREE_FNAME) { xfree(match->cp_fname); } - for (int i = 0; i < CPT_COUNT; i++) { - xfree(match->cp_text[i]); - } + free_cptext(match->cp_text); tv_clear(&match->cp_user_data); xfree(match); } while (compl_curr_match != NULL && !is_first_match(compl_curr_match)); @@ -2459,9 +2463,7 @@ static int ins_compl_add_tv(typval_T *const tv, const Direction dir, bool fast) CLEAR_FIELD(cptext); } if (word == NULL || (!empty && *word == NUL)) { - for (size_t i = 0; i < CPT_COUNT; i++) { - xfree(cptext[i]); - } + free_cptext(cptext); tv_clear(&user_data); return FAIL; } -- cgit From 66f1563c7a48d76f99c89e32de030e57af2abfb4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 4 Dec 2023 20:29:51 +0800 Subject: refactor(terminal): only remove const qualifier when necessary (#26386) --- src/nvim/api/vim.c | 23 ++++++++++++----------- src/nvim/channel.c | 17 +++++++++-------- src/nvim/terminal.c | 8 ++++---- src/nvim/terminal.h | 2 +- 4 files changed, 26 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 270f2e4432..db08cb8cf0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1017,18 +1017,19 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) } } - TerminalOptions topts; Channel *chan = channel_alloc(kChannelStreamInternal); chan->stream.internal.cb = cb; chan->stream.internal.closed = false; - topts.data = chan; - // 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; - topts.write_cb = term_write; - topts.resize_cb = term_resize; - topts.close_cb = term_close; + TerminalOptions topts = { + .data = chan, + // NB: overridden in terminal_check_size if a window is already + // displaying the buffer + .width = (uint16_t)MAX(curwin->w_width_inner - win_col_off(curwin), 0), + .height = (uint16_t)curwin->w_height_inner, + .write_cb = term_write, + .resize_cb = term_resize, + .close_cb = term_close, + }; channel_incref(chan); terminal_open(&chan->term, buf, topts); if (chan->term != NULL) { @@ -1038,7 +1039,7 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) return (Integer)chan->id; } -static void term_write(char *buf, size_t size, void *data) // NOLINT(readability-non-const-parameter) +static void term_write(const char *buf, size_t size, void *data) { Channel *chan = data; LuaRef cb = chan->stream.internal.cb; @@ -1048,7 +1049,7 @@ static void term_write(char *buf, size_t size, void *data) // NOLINT(readabilit MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, INTEGER_OBJ((Integer)chan->id)); ADD_C(args, BUFFER_OBJ(terminal_buf(chan->term))); - ADD_C(args, STRING_OBJ(((String){ .data = buf, .size = size }))); + ADD_C(args, STRING_OBJ(((String){ .data = (char *)buf, .size = size }))); textlock++; nlua_call_ref(cb, "input", args, false, NULL); textlock--; diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 24793bcb2a..767c8d29b8 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -794,19 +794,20 @@ static void channel_callback_call(Channel *chan, CallbackReader *reader) /// and `buf` is assumed to be a new, unmodified buffer. void channel_terminal_open(buf_T *buf, Channel *chan) { - TerminalOptions topts; - topts.data = chan; - topts.width = chan->stream.pty.width; - topts.height = chan->stream.pty.height; - topts.write_cb = term_write; - topts.resize_cb = term_resize; - topts.close_cb = term_close; + TerminalOptions topts = { + .data = chan, + .width = chan->stream.pty.width, + .height = chan->stream.pty.height, + .write_cb = term_write, + .resize_cb = term_resize, + .close_cb = term_close, + }; buf->b_p_channel = (OptInt)chan->id; // 'channel' option channel_incref(chan); terminal_open(&chan->term, buf, topts); } -static void term_write(char *buf, size_t size, void *data) +static void term_write(const char *buf, size_t size, void *data) { Channel *chan = data; if (chan->stream.proc.in.closed) { diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 03a7744b18..fda6aa41e8 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -188,7 +188,7 @@ void terminal_teardown(void) static void term_output_callback(const char *s, size_t len, void *user_data) { - terminal_send((Terminal *)user_data, (char *)s, len); + terminal_send((Terminal *)user_data, s, len); } // public API {{{ @@ -680,7 +680,7 @@ void terminal_destroy(Terminal **termpp) } } -void terminal_send(Terminal *term, char *data, size_t size) +static void terminal_send(Terminal *term, const char *data, size_t size) { if (term->closed) { return; @@ -762,7 +762,7 @@ void terminal_paste(int count, char **y_array, size_t y_size) vterm_keyboard_end_paste(curbuf->terminal->vt); } -void terminal_send_key(Terminal *term, int c) +static void terminal_send_key(Terminal *term, int c) { VTermModifier mod = VTERM_MOD_NONE; @@ -780,7 +780,7 @@ void terminal_send_key(Terminal *term, int c) } } -void terminal_receive(Terminal *term, char *data, size_t len) +void terminal_receive(Terminal *term, const char *data, size_t len) { if (!data) { return; diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h index 66cad7ee7a..db62bd2a5b 100644 --- a/src/nvim/terminal.h +++ b/src/nvim/terminal.h @@ -4,7 +4,7 @@ #include typedef struct terminal Terminal; -typedef void (*terminal_write_cb)(char *buffer, size_t size, void *data); +typedef void (*terminal_write_cb)(const char *buffer, size_t size, void *data); typedef void (*terminal_resize_cb)(uint16_t width, uint16_t height, void *data); typedef void (*terminal_close_cb)(void *data); -- cgit From e5d7003b02c9af96c51ea5638e07eea25057a216 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:21:38 +0100 Subject: build: rework formatting to use add_glob_target This will ensure that we can pass flags and make adjustments from the top level cmake file instead of digging through the cmake directory. More importantly, this will only format files that have been changed. This has a slightly higher initial cost compared to previous solution as all files must be initially formatted, but the gained speed up should more than make up for it quickly. `make formatlua` is always run due to a quirk of stylua of always changing modification time of the file regardless if there were any changes. This is not a major blocker as stylua is very fast. --- src/nvim/CMakeLists.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 6a01632040..0cdce539eb 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -879,12 +879,11 @@ add_glob_target( FLAGS -c ${UNCRUSTIFY_CONFIG} -q --check FILES ${LINT_NVIM_SOURCES}) -add_custom_target(formatc - COMMAND ${CMAKE_COMMAND} - -D FORMAT_PRG=${UNCRUSTIFY_PRG} - -D LANG=c - -P ${PROJECT_SOURCE_DIR}/cmake/Format.cmake - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) +add_glob_target( + TARGET formatc + COMMAND ${UNCRUSTIFY_PRG} + FLAGS -c ${UNCRUSTIFY_CONFIG} --replace --no-backup + FILES ${LINT_NVIM_SOURCES}) add_dependencies(lintc-uncrustify uncrustify_update_config) add_dependencies(formatc uncrustify_update_config) -- cgit From 45fe4d11add933df76a2ea4bf52ce8904f4a778b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 4 Dec 2023 13:31:57 -0800 Subject: build: enable lintlua for src/ dir #26395 Problem: Not all Lua code is checked by stylua. Automating code-style is an important mechanism for reducing time spent on accidental (non-essential) complexity. Solution: - Enable lintlua for `src/` directory. followup to 517f0cc634b985057da5b95cf4ad659ee456a77e --- src/nvim/api/dispatch_deprecated.lua | 132 +- src/nvim/auevents.lua | 300 +- src/nvim/eval.lua | 16 +- src/nvim/ex_cmds.lua | 4478 ++++++++++++++-------------- src/nvim/generators/c_grammar.lua | 90 +- src/nvim/generators/dump_bin_array.lua | 4 +- src/nvim/generators/gen_api_dispatch.lua | 507 +++- src/nvim/generators/gen_api_ui_events.lua | 110 +- src/nvim/generators/gen_char_blob.lua | 31 +- src/nvim/generators/gen_declarations.lua | 154 +- src/nvim/generators/gen_eval.lua | 43 +- src/nvim/generators/gen_events.lua | 10 +- src/nvim/generators/gen_ex_cmds.lua | 81 +- src/nvim/generators/gen_options.lua | 107 +- src/nvim/generators/gen_unicode_tables.lua | 33 +- src/nvim/generators/gen_vimvim.lua | 16 +- src/nvim/generators/hashy.lua | 83 +- src/nvim/generators/preload.lua | 4 +- 18 files changed, 3223 insertions(+), 2976 deletions(-) (limited to 'src') diff --git a/src/nvim/api/dispatch_deprecated.lua b/src/nvim/api/dispatch_deprecated.lua index 5650a77ac0..7a92789f79 100644 --- a/src/nvim/api/dispatch_deprecated.lua +++ b/src/nvim/api/dispatch_deprecated.lua @@ -1,69 +1,69 @@ local deprecated_aliases = { - nvim_buf_add_highlight="buffer_add_highlight", - nvim_buf_clear_highlight="buffer_clear_highlight", - nvim_buf_get_lines="buffer_get_lines", - nvim_buf_get_mark="buffer_get_mark", - nvim_buf_get_name="buffer_get_name", - nvim_buf_get_number="buffer_get_number", - nvim_buf_get_option="buffer_get_option", - nvim_buf_get_var="buffer_get_var", - nvim_buf_is_valid="buffer_is_valid", - nvim_buf_line_count="buffer_line_count", - nvim_buf_set_lines="buffer_set_lines", - nvim_buf_set_name="buffer_set_name", - nvim_buf_set_option="buffer_set_option", - nvim_call_function="vim_call_function", - nvim_command="vim_command", - nvim_command_output="vim_command_output", - nvim_del_current_line="vim_del_current_line", - nvim_err_write="vim_err_write", - nvim_err_writeln="vim_report_error", - nvim_eval="vim_eval", - nvim_feedkeys="vim_feedkeys", - nvim_get_api_info="vim_get_api_info", - nvim_get_color_by_name="vim_name_to_color", - nvim_get_color_map="vim_get_color_map", - nvim_get_current_buf="vim_get_current_buffer", - nvim_get_current_line="vim_get_current_line", - nvim_get_current_tabpage="vim_get_current_tabpage", - nvim_get_current_win="vim_get_current_window", - nvim_get_option="vim_get_option", - nvim_get_var="vim_get_var", - nvim_get_vvar="vim_get_vvar", - nvim_input="vim_input", - nvim_list_bufs="vim_get_buffers", - nvim_list_runtime_paths="vim_list_runtime_paths", - nvim_list_tabpages="vim_get_tabpages", - nvim_list_wins="vim_get_windows", - nvim_out_write="vim_out_write", - nvim_replace_termcodes="vim_replace_termcodes", - nvim_set_current_buf="vim_set_current_buffer", - nvim_set_current_dir="vim_change_directory", - nvim_set_current_line="vim_set_current_line", - nvim_set_current_tabpage="vim_set_current_tabpage", - nvim_set_current_win="vim_set_current_window", - nvim_set_option="vim_set_option", - nvim_strwidth="vim_strwidth", - nvim_subscribe="vim_subscribe", - nvim_tabpage_get_var="tabpage_get_var", - nvim_tabpage_get_win="tabpage_get_window", - nvim_tabpage_is_valid="tabpage_is_valid", - nvim_tabpage_list_wins="tabpage_get_windows", - nvim_ui_detach="ui_detach", - nvim_ui_try_resize="ui_try_resize", - nvim_unsubscribe="vim_unsubscribe", - nvim_win_get_buf="window_get_buffer", - nvim_win_get_cursor="window_get_cursor", - nvim_win_get_height="window_get_height", - nvim_win_get_option="window_get_option", - nvim_win_get_position="window_get_position", - nvim_win_get_tabpage="window_get_tabpage", - nvim_win_get_var="window_get_var", - nvim_win_get_width="window_get_width", - nvim_win_is_valid="window_is_valid", - nvim_win_set_cursor="window_set_cursor", - nvim_win_set_height="window_set_height", - nvim_win_set_option="window_set_option", - nvim_win_set_width="window_set_width", + nvim_buf_add_highlight = 'buffer_add_highlight', + nvim_buf_clear_highlight = 'buffer_clear_highlight', + nvim_buf_get_lines = 'buffer_get_lines', + nvim_buf_get_mark = 'buffer_get_mark', + nvim_buf_get_name = 'buffer_get_name', + nvim_buf_get_number = 'buffer_get_number', + nvim_buf_get_option = 'buffer_get_option', + nvim_buf_get_var = 'buffer_get_var', + nvim_buf_is_valid = 'buffer_is_valid', + nvim_buf_line_count = 'buffer_line_count', + nvim_buf_set_lines = 'buffer_set_lines', + nvim_buf_set_name = 'buffer_set_name', + nvim_buf_set_option = 'buffer_set_option', + nvim_call_function = 'vim_call_function', + nvim_command = 'vim_command', + nvim_command_output = 'vim_command_output', + nvim_del_current_line = 'vim_del_current_line', + nvim_err_write = 'vim_err_write', + nvim_err_writeln = 'vim_report_error', + nvim_eval = 'vim_eval', + nvim_feedkeys = 'vim_feedkeys', + nvim_get_api_info = 'vim_get_api_info', + nvim_get_color_by_name = 'vim_name_to_color', + nvim_get_color_map = 'vim_get_color_map', + nvim_get_current_buf = 'vim_get_current_buffer', + nvim_get_current_line = 'vim_get_current_line', + nvim_get_current_tabpage = 'vim_get_current_tabpage', + nvim_get_current_win = 'vim_get_current_window', + nvim_get_option = 'vim_get_option', + nvim_get_var = 'vim_get_var', + nvim_get_vvar = 'vim_get_vvar', + nvim_input = 'vim_input', + nvim_list_bufs = 'vim_get_buffers', + nvim_list_runtime_paths = 'vim_list_runtime_paths', + nvim_list_tabpages = 'vim_get_tabpages', + nvim_list_wins = 'vim_get_windows', + nvim_out_write = 'vim_out_write', + nvim_replace_termcodes = 'vim_replace_termcodes', + nvim_set_current_buf = 'vim_set_current_buffer', + nvim_set_current_dir = 'vim_change_directory', + nvim_set_current_line = 'vim_set_current_line', + nvim_set_current_tabpage = 'vim_set_current_tabpage', + nvim_set_current_win = 'vim_set_current_window', + nvim_set_option = 'vim_set_option', + nvim_strwidth = 'vim_strwidth', + nvim_subscribe = 'vim_subscribe', + nvim_tabpage_get_var = 'tabpage_get_var', + nvim_tabpage_get_win = 'tabpage_get_window', + nvim_tabpage_is_valid = 'tabpage_is_valid', + nvim_tabpage_list_wins = 'tabpage_get_windows', + nvim_ui_detach = 'ui_detach', + nvim_ui_try_resize = 'ui_try_resize', + nvim_unsubscribe = 'vim_unsubscribe', + nvim_win_get_buf = 'window_get_buffer', + nvim_win_get_cursor = 'window_get_cursor', + nvim_win_get_height = 'window_get_height', + nvim_win_get_option = 'window_get_option', + nvim_win_get_position = 'window_get_position', + nvim_win_get_tabpage = 'window_get_tabpage', + nvim_win_get_var = 'window_get_var', + nvim_win_get_width = 'window_get_width', + nvim_win_is_valid = 'window_is_valid', + nvim_win_set_cursor = 'window_set_cursor', + nvim_win_set_height = 'window_set_height', + nvim_win_set_option = 'window_set_option', + nvim_win_set_width = 'window_set_width', } return deprecated_aliases diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index 696df7c534..11d1597236 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -1,172 +1,172 @@ return { events = { - 'BufAdd', -- after adding a buffer to the buffer list - 'BufDelete', -- deleting a buffer from the buffer list - 'BufEnter', -- after entering a buffer - 'BufFilePost', -- after renaming a buffer - 'BufFilePre', -- before renaming a buffer - 'BufHidden', -- just after buffer becomes hidden - 'BufLeave', -- before leaving a buffer - 'BufModifiedSet', -- after the 'modified' state of a buffer changes - 'BufNew', -- after creating any buffer - 'BufNewFile', -- when creating a buffer for a new file - 'BufReadCmd', -- read buffer using command - 'BufReadPost', -- after reading a buffer - 'BufReadPre', -- before reading a buffer - 'BufUnload', -- just before unloading a buffer - 'BufWinEnter', -- after showing a buffer in a window - 'BufWinLeave', -- just after buffer removed from window - 'BufWipeout', -- just before really deleting a buffer - 'BufWriteCmd', -- write buffer using command - 'BufWritePost', -- after writing a buffer - 'BufWritePre', -- before writing a buffer - 'ChanInfo', -- info was received about channel - 'ChanOpen', -- channel was opened - 'CmdUndefined', -- command undefined - 'CmdWinEnter', -- after entering the cmdline window - 'CmdWinLeave', -- before leaving the cmdline window - 'CmdlineChanged', -- command line was modified - 'CmdlineEnter', -- after entering cmdline mode - 'CmdlineLeave', -- before leaving cmdline mode - 'ColorScheme', -- after loading a colorscheme - 'ColorSchemePre', -- before loading a colorscheme - 'CompleteChanged', -- after popup menu changed - 'CompleteDone', -- after finishing insert complete - 'CompleteDonePre', -- idem, before clearing info - 'CursorHold', -- cursor in same position for a while - 'CursorHoldI', -- idem, in Insert mode - 'CursorMoved', -- cursor was moved - 'CursorMovedI', -- cursor was moved in Insert mode - 'DiagnosticChanged', -- diagnostics in a buffer were modified - 'DiffUpdated', -- diffs have been updated - 'DirChanged', -- directory changed - 'DirChangedPre', -- directory is going to change - 'EncodingChanged', -- after changing the 'encoding' option - 'ExitPre', -- before exiting - 'FileAppendCmd', -- append to a file using command - 'FileAppendPost', -- after appending to a file - 'FileAppendPre', -- before appending to a file - 'FileChangedRO', -- before first change to read-only file - 'FileChangedShell', -- after shell command that changed file - 'FileChangedShellPost', -- after (not) reloading changed file - 'FileReadCmd', -- read from a file using command - 'FileReadPost', -- after reading a file - 'FileReadPre', -- before reading a file - 'FileType', -- new file type detected (user defined) - 'FileWriteCmd', -- write to a file using command - 'FileWritePost', -- after writing a file - 'FileWritePre', -- before writing a file - 'FilterReadPost', -- after reading from a filter - 'FilterReadPre', -- before reading from a filter - 'FilterWritePost', -- after writing to a filter - 'FilterWritePre', -- before writing to a filter - 'FocusGained', -- got the focus - 'FocusLost', -- lost the focus to another app - 'FuncUndefined', -- if calling a function which doesn't exist - 'GUIEnter', -- after starting the GUI - 'GUIFailed', -- after starting the GUI failed - 'InsertChange', -- when changing Insert/Replace mode - 'InsertCharPre', -- before inserting a char - 'InsertEnter', -- when entering Insert mode - 'InsertLeave', -- just after leaving Insert mode - 'InsertLeavePre', -- just before leaving Insert mode - 'LspAttach', -- after an LSP client attaches to a buffer - 'LspDetach', -- after an LSP client detaches from a buffer - 'LspRequest', -- after an LSP request is started, canceled, or completed - 'LspNotify', -- after an LSP notice has been sent to the server - 'LspTokenUpdate', -- after a visible LSP token is updated - 'LspProgress', -- after a LSP progress update - 'MenuPopup', -- just before popup menu is displayed - 'ModeChanged', -- after changing the mode - 'OptionSet', -- after setting any option - 'QuickFixCmdPost', -- after :make, :grep etc. - 'QuickFixCmdPre', -- before :make, :grep etc. - 'QuitPre', -- before :quit - 'RecordingEnter', -- when starting to record a macro - 'RecordingLeave', -- just before a macro stops recording - 'RemoteReply', -- upon string reception from a remote vim - 'SafeState', -- going to wait for a character - 'SearchWrapped', -- after the search wrapped around - 'SessionLoadPost', -- after loading a session file - 'ShellCmdPost', -- after ":!cmd" - 'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd". - 'Signal', -- after nvim process received a signal - 'SourceCmd', -- sourcing a Vim script using command - 'SourcePost', -- after sourcing a Vim script - 'SourcePre', -- before sourcing a Vim script - 'SpellFileMissing', -- spell file missing - 'StdinReadPost', -- after reading from stdin - 'StdinReadPre', -- before reading from stdin - 'SwapExists', -- found existing swap file - 'Syntax', -- syntax selected - 'TabClosed', -- a tab has closed - 'TabEnter', -- after entering a tab page - 'TabLeave', -- before leaving a tab page - 'TabNew', -- when creating a new tab - 'TabNewEntered', -- after entering a new tab - 'TermChanged', -- after changing 'term' - 'TermClose', -- after the process exits - 'TermEnter', -- after entering Terminal mode - 'TermLeave', -- after leaving Terminal mode - 'TermOpen', -- after opening a terminal buffer - 'TermResponse', -- after setting "v:termresponse" - 'TextChanged', -- text was modified - 'TextChangedI', -- text was modified in Insert mode(no popup) - 'TextChangedP', -- text was modified in Insert mode(popup) - 'TextChangedT', -- text was modified in Terminal mode - 'TextYankPost', -- after a yank or delete was done (y, d, c) - 'UIEnter', -- after UI attaches - 'UILeave', -- after UI detaches - 'User', -- user defined autocommand - 'VimEnter', -- after starting Vim - 'VimLeave', -- before exiting Vim - 'VimLeavePre', -- before exiting Vim and writing ShaDa file - 'VimResized', -- after Vim window was resized - 'VimResume', -- after Nvim is resumed - 'VimSuspend', -- before Nvim is suspended - 'WinClosed', -- after closing a window - 'WinEnter', -- after entering a window - 'WinLeave', -- before leaving a window - 'WinNew', -- when entering a new window - 'WinResized', -- after a window was resized - 'WinScrolled', -- after a window was scrolled or resized + 'BufAdd', -- after adding a buffer to the buffer list + 'BufDelete', -- deleting a buffer from the buffer list + 'BufEnter', -- after entering a buffer + 'BufFilePost', -- after renaming a buffer + 'BufFilePre', -- before renaming a buffer + 'BufHidden', -- just after buffer becomes hidden + 'BufLeave', -- before leaving a buffer + 'BufModifiedSet', -- after the 'modified' state of a buffer changes + 'BufNew', -- after creating any buffer + 'BufNewFile', -- when creating a buffer for a new file + 'BufReadCmd', -- read buffer using command + 'BufReadPost', -- after reading a buffer + 'BufReadPre', -- before reading a buffer + 'BufUnload', -- just before unloading a buffer + 'BufWinEnter', -- after showing a buffer in a window + 'BufWinLeave', -- just after buffer removed from window + 'BufWipeout', -- just before really deleting a buffer + 'BufWriteCmd', -- write buffer using command + 'BufWritePost', -- after writing a buffer + 'BufWritePre', -- before writing a buffer + 'ChanInfo', -- info was received about channel + 'ChanOpen', -- channel was opened + 'CmdUndefined', -- command undefined + 'CmdWinEnter', -- after entering the cmdline window + 'CmdWinLeave', -- before leaving the cmdline window + 'CmdlineChanged', -- command line was modified + 'CmdlineEnter', -- after entering cmdline mode + 'CmdlineLeave', -- before leaving cmdline mode + 'ColorScheme', -- after loading a colorscheme + 'ColorSchemePre', -- before loading a colorscheme + 'CompleteChanged', -- after popup menu changed + 'CompleteDone', -- after finishing insert complete + 'CompleteDonePre', -- idem, before clearing info + 'CursorHold', -- cursor in same position for a while + 'CursorHoldI', -- idem, in Insert mode + 'CursorMoved', -- cursor was moved + 'CursorMovedI', -- cursor was moved in Insert mode + 'DiagnosticChanged', -- diagnostics in a buffer were modified + 'DiffUpdated', -- diffs have been updated + 'DirChanged', -- directory changed + 'DirChangedPre', -- directory is going to change + 'EncodingChanged', -- after changing the 'encoding' option + 'ExitPre', -- before exiting + 'FileAppendCmd', -- append to a file using command + 'FileAppendPost', -- after appending to a file + 'FileAppendPre', -- before appending to a file + 'FileChangedRO', -- before first change to read-only file + 'FileChangedShell', -- after shell command that changed file + 'FileChangedShellPost', -- after (not) reloading changed file + 'FileReadCmd', -- read from a file using command + 'FileReadPost', -- after reading a file + 'FileReadPre', -- before reading a file + 'FileType', -- new file type detected (user defined) + 'FileWriteCmd', -- write to a file using command + 'FileWritePost', -- after writing a file + 'FileWritePre', -- before writing a file + 'FilterReadPost', -- after reading from a filter + 'FilterReadPre', -- before reading from a filter + 'FilterWritePost', -- after writing to a filter + 'FilterWritePre', -- before writing to a filter + 'FocusGained', -- got the focus + 'FocusLost', -- lost the focus to another app + 'FuncUndefined', -- if calling a function which doesn't exist + 'GUIEnter', -- after starting the GUI + 'GUIFailed', -- after starting the GUI failed + 'InsertChange', -- when changing Insert/Replace mode + 'InsertCharPre', -- before inserting a char + 'InsertEnter', -- when entering Insert mode + 'InsertLeave', -- just after leaving Insert mode + 'InsertLeavePre', -- just before leaving Insert mode + 'LspAttach', -- after an LSP client attaches to a buffer + 'LspDetach', -- after an LSP client detaches from a buffer + 'LspRequest', -- after an LSP request is started, canceled, or completed + 'LspNotify', -- after an LSP notice has been sent to the server + 'LspTokenUpdate', -- after a visible LSP token is updated + 'LspProgress', -- after a LSP progress update + 'MenuPopup', -- just before popup menu is displayed + 'ModeChanged', -- after changing the mode + 'OptionSet', -- after setting any option + 'QuickFixCmdPost', -- after :make, :grep etc. + 'QuickFixCmdPre', -- before :make, :grep etc. + 'QuitPre', -- before :quit + 'RecordingEnter', -- when starting to record a macro + 'RecordingLeave', -- just before a macro stops recording + 'RemoteReply', -- upon string reception from a remote vim + 'SafeState', -- going to wait for a character + 'SearchWrapped', -- after the search wrapped around + 'SessionLoadPost', -- after loading a session file + 'ShellCmdPost', -- after ":!cmd" + 'ShellFilterPost', -- after ":1,2!cmd", ":w !cmd", ":r !cmd". + 'Signal', -- after nvim process received a signal + 'SourceCmd', -- sourcing a Vim script using command + 'SourcePost', -- after sourcing a Vim script + 'SourcePre', -- before sourcing a Vim script + 'SpellFileMissing', -- spell file missing + 'StdinReadPost', -- after reading from stdin + 'StdinReadPre', -- before reading from stdin + 'SwapExists', -- found existing swap file + 'Syntax', -- syntax selected + 'TabClosed', -- a tab has closed + 'TabEnter', -- after entering a tab page + 'TabLeave', -- before leaving a tab page + 'TabNew', -- when creating a new tab + 'TabNewEntered', -- after entering a new tab + 'TermChanged', -- after changing 'term' + 'TermClose', -- after the process exits + 'TermEnter', -- after entering Terminal mode + 'TermLeave', -- after leaving Terminal mode + 'TermOpen', -- after opening a terminal buffer + 'TermResponse', -- after setting "v:termresponse" + 'TextChanged', -- text was modified + 'TextChangedI', -- text was modified in Insert mode(no popup) + 'TextChangedP', -- text was modified in Insert mode(popup) + 'TextChangedT', -- text was modified in Terminal mode + 'TextYankPost', -- after a yank or delete was done (y, d, c) + 'UIEnter', -- after UI attaches + 'UILeave', -- after UI detaches + 'User', -- user defined autocommand + 'VimEnter', -- after starting Vim + 'VimLeave', -- before exiting Vim + 'VimLeavePre', -- before exiting Vim and writing ShaDa file + 'VimResized', -- after Vim window was resized + 'VimResume', -- after Nvim is resumed + 'VimSuspend', -- before Nvim is suspended + 'WinClosed', -- after closing a window + 'WinEnter', -- after entering a window + 'WinLeave', -- before leaving a window + 'WinNew', -- when entering a new window + 'WinResized', -- after a window was resized + 'WinScrolled', -- after a window was scrolled or resized }, aliases = { { 'BufCreate', - 'BufAdd' + 'BufAdd', }, { 'BufRead', - 'BufReadPost' + 'BufReadPost', }, { 'BufWrite', - 'BufWritePre' + 'BufWritePre', }, { 'FileEncoding', - 'EncodingChanged' + 'EncodingChanged', }, }, -- List of nvim-specific events or aliases for the purpose of generating -- syntax file nvim_specific = { - BufModifiedSet=true, - DiagnosticChanged=true, - LspAttach=true, - LspDetach=true, - LspNotify=true, - LspRequest=true, - LspProgress=true, - LspTokenUpdate=true, - RecordingEnter=true, - RecordingLeave=true, - Signal=true, - TabNewEntered=true, - TermClose=true, - TermOpen=true, - UIEnter=true, - UILeave=true, + BufModifiedSet = true, + DiagnosticChanged = true, + LspAttach = true, + LspDetach = true, + LspNotify = true, + LspRequest = true, + LspProgress = true, + LspTokenUpdate = true, + RecordingEnter = true, + RecordingLeave = true, + Signal = true, + TabNewEntered = true, + TermClose = true, + TermOpen = true, + UIEnter = true, + UILeave = true, }, } diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 55f4721c3a..59423808be 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -2114,7 +2114,7 @@ M.funcs = { name = 'execute', params = { { 'command', 'string|string[]' }, - { 'silent', "''|'silent'|'silent!'" } + { 'silent', "''|'silent'|'silent!'" }, }, returns = 'string', signature = 'execute({command} [, {silent}])', @@ -4519,7 +4519,7 @@ M.funcs = { name = 'getwininfo', params = { { 'winid', 'integer' } }, signature = 'getwininfo([{winid}])', - returns = 'vim.fn.getwininfo.ret.item[]' + returns = 'vim.fn.getwininfo.ret.item[]', }, getwinpos = { args = { 0, 1 }, @@ -6297,7 +6297,7 @@ M.funcs = { ]], name = 'maplist', params = {}, - signature = 'maplist([{abbr}])' + signature = 'maplist([{abbr}])', }, mapnew = { args = 2, @@ -9905,7 +9905,7 @@ M.funcs = { name = 'sign_jump', params = { { 'id', 'integer' }, { 'group', 'string' }, { 'buf', 'integer|string' } }, signature = 'sign_jump({id}, {group}, {buf})', - returns = 'integer' + returns = 'integer', }, sign_place = { args = { 4, 5 }, @@ -9968,7 +9968,7 @@ M.funcs = { { 'dict', 'vim.fn.sign_place.dict' }, }, signature = 'sign_place({id}, {group}, {name}, {buf} [, {dict}])', - returns = 'integer' + returns = 'integer', }, sign_placelist = { args = 1, @@ -10035,7 +10035,7 @@ M.funcs = { name = 'sign_placelist', params = { { 'list', 'vim.fn.sign_placelist.list.item[]' } }, signature = 'sign_placelist({list})', - returns = 'integer[]' + returns = 'integer[]', }, sign_undefine = { args = { 0, 1 }, @@ -10570,7 +10570,7 @@ M.funcs = { signature = 'stdpath({what})', }, state = { - args = {0, 1}, + args = { 0, 1 }, base = 1, desc = [=[ Return a string which contains characters indicating the @@ -12698,7 +12698,7 @@ M.funcs = { name = 'winsaveview', params = {}, signature = 'winsaveview()', - returns = 'vim.fn.winsaveview.ret' + returns = 'vim.fn.winsaveview.ret', }, winwidth = { args = 1, diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 4859a70553..551d228862 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -4,3358 +4,3358 @@ local module = {} -- Description of the values below is contained in ex_cmds_defs.h file. -- "EX_" prefix is omitted. -local RANGE = 0x001 -local BANG = 0x002 -local EXTRA = 0x004 -local XFILE = 0x008 -local NOSPC = 0x010 -local DFLALL = 0x020 -local WHOLEFOLD = 0x040 -local NEEDARG = 0x080 -local TRLBAR = 0x100 -local REGSTR = 0x200 -local COUNT = 0x400 -local NOTRLCOM = 0x800 -local ZEROR = 0x1000 -local CTRLV = 0x2000 -local CMDARG = 0x4000 -local BUFNAME = 0x8000 -local BUFUNL = 0x10000 -local ARGOPT = 0x20000 -local SBOXOK = 0x40000 -local CMDWIN = 0x80000 -local MODIFY = 0x100000 -local FLAGS = 0x200000 -local LOCK_OK = 0x1000000 -local PREVIEW = 0x8000000 -local FILES = bit.bor(XFILE, EXTRA) -local WORD1 = bit.bor(EXTRA, NOSPC) -local FILE1 = bit.bor(FILES, NOSPC) +local RANGE = 0x001 +local BANG = 0x002 +local EXTRA = 0x004 +local XFILE = 0x008 +local NOSPC = 0x010 +local DFLALL = 0x020 +local WHOLEFOLD = 0x040 +local NEEDARG = 0x080 +local TRLBAR = 0x100 +local REGSTR = 0x200 +local COUNT = 0x400 +local NOTRLCOM = 0x800 +local ZEROR = 0x1000 +local CTRLV = 0x2000 +local CMDARG = 0x4000 +local BUFNAME = 0x8000 +local BUFUNL = 0x10000 +local ARGOPT = 0x20000 +local SBOXOK = 0x40000 +local CMDWIN = 0x80000 +local MODIFY = 0x100000 +local FLAGS = 0x200000 +local LOCK_OK = 0x1000000 +local PREVIEW = 0x8000000 +local FILES = bit.bor(XFILE, EXTRA) +local WORD1 = bit.bor(EXTRA, NOSPC) +local FILE1 = bit.bor(FILES, NOSPC) module.flags = { RANGE = RANGE, DFLALL = DFLALL, - PREVIEW = PREVIEW + PREVIEW = PREVIEW, } -- The following table is described in ex_cmds_defs.h file. module.cmds = { { - command='append', - flags=bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_append', + command = 'append', + flags = bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_append', }, { - command='abbreviate', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'abbreviate', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='abclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abclear', + command = 'abclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abclear', }, { - command='aboveleft', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'aboveleft', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='all', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_all', + command = 'all', + flags = bit.bor(BANG, RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_all', }, { - command='amenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'amenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='anoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'anoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='args', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_args', + command = 'args', + flags = bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_args', }, { - command='argadd', - flags=bit.bor(BANG, RANGE, ZEROR, FILES, TRLBAR), - addr_type='ADDR_ARGUMENTS', - func='ex_argadd', + command = 'argadd', + flags = bit.bor(BANG, RANGE, ZEROR, FILES, TRLBAR), + addr_type = 'ADDR_ARGUMENTS', + func = 'ex_argadd', }, { - command='argdelete', - flags=bit.bor(BANG, RANGE, FILES, TRLBAR), - addr_type='ADDR_ARGUMENTS', - func='ex_argdelete', + command = 'argdelete', + flags = bit.bor(BANG, RANGE, FILES, TRLBAR), + addr_type = 'ADDR_ARGUMENTS', + func = 'ex_argdelete', }, { - command='argdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_ARGUMENTS', - func='ex_listdo', + command = 'argdo', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_ARGUMENTS', + func = 'ex_listdo', }, { - command='argdedupe', - flags=TRLBAR, - addr_type='ADDR_NONE', - func='ex_argdedupe', + command = 'argdedupe', + flags = TRLBAR, + addr_type = 'ADDR_NONE', + func = 'ex_argdedupe', }, { - command='argedit', - flags=bit.bor(BANG, NEEDARG, RANGE, ZEROR, FILES, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_ARGUMENTS', - func='ex_argedit', + command = 'argedit', + flags = bit.bor(BANG, NEEDARG, RANGE, ZEROR, FILES, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_ARGUMENTS', + func = 'ex_argedit', }, { - command='argglobal', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_args', + command = 'argglobal', + flags = bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_args', }, { - command='arglocal', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_args', + command = 'arglocal', + flags = bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_args', }, { - command='argument', - flags=bit.bor(BANG, RANGE, COUNT, EXTRA, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_ARGUMENTS', - func='ex_argument', + command = 'argument', + flags = bit.bor(BANG, RANGE, COUNT, EXTRA, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_ARGUMENTS', + func = 'ex_argument', }, { - command='ascii', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='do_ascii', + command = 'ascii', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'do_ascii', }, { - command='autocmd', - flags=bit.bor(BANG, EXTRA, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_autocmd', + command = 'autocmd', + flags = bit.bor(BANG, EXTRA, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_autocmd', }, { - command='augroup', - flags=bit.bor(BANG, WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_autocmd', + command = 'augroup', + flags = bit.bor(BANG, WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_autocmd', }, { - command='aunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'aunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='buffer', - flags=bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, CMDARG, TRLBAR), - addr_type='ADDR_BUFFERS', - func='ex_buffer', + command = 'buffer', + flags = bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, CMDARG, TRLBAR), + addr_type = 'ADDR_BUFFERS', + func = 'ex_buffer', }, { - command='bNext', - flags=bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bprevious', + command = 'bNext', + flags = bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bprevious', }, { - command='ball', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_buffer_all', + command = 'ball', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_buffer_all', }, { - command='badd', - flags=bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'badd', + flags = bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='balt', - flags=bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'balt', + flags = bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='bdelete', - flags=bit.bor(BANG, RANGE, BUFNAME, COUNT, EXTRA, TRLBAR), - addr_type='ADDR_BUFFERS', - func='ex_bunload', + command = 'bdelete', + flags = bit.bor(BANG, RANGE, BUFNAME, COUNT, EXTRA, TRLBAR), + addr_type = 'ADDR_BUFFERS', + func = 'ex_bunload', }, { - command='belowright', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'belowright', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='bfirst', - flags=bit.bor(BANG, RANGE, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_brewind', + command = 'bfirst', + flags = bit.bor(BANG, RANGE, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_brewind', }, { - command='blast', - flags=bit.bor(BANG, RANGE, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_blast', + command = 'blast', + flags = bit.bor(BANG, RANGE, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_blast', }, { - command='bmodified', - flags=bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bmodified', + command = 'bmodified', + flags = bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bmodified', }, { - command='bnext', - flags=bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bnext', + command = 'bnext', + flags = bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bnext', }, { - command='botright', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'botright', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='bprevious', - flags=bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bprevious', + command = 'bprevious', + flags = bit.bor(BANG, RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bprevious', }, { - command='brewind', - flags=bit.bor(BANG, RANGE, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_brewind', + command = 'brewind', + flags = bit.bor(BANG, RANGE, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_brewind', }, { - command='break', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_break', + command = 'break', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_break', }, { - command='breakadd', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_breakadd', + command = 'breakadd', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_breakadd', }, { - command='breakdel', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_breakdel', + command = 'breakdel', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_breakdel', }, { - command='breaklist', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_breaklist', + command = 'breaklist', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_breaklist', }, { - command='browse', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'browse', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='buffers', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='buflist_list', + command = 'buffers', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'buflist_list', }, { - command='bufdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_BUFFERS', - func='ex_listdo', + command = 'bufdo', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_BUFFERS', + func = 'ex_listdo', }, { - command='bunload', - flags=bit.bor(BANG, RANGE, BUFNAME, COUNT, EXTRA, TRLBAR), - addr_type='ADDR_LOADED_BUFFERS', - func='ex_bunload', + command = 'bunload', + flags = bit.bor(BANG, RANGE, BUFNAME, COUNT, EXTRA, TRLBAR), + addr_type = 'ADDR_LOADED_BUFFERS', + func = 'ex_bunload', }, { - command='bwipeout', - flags=bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, TRLBAR), - addr_type='ADDR_BUFFERS', - func='ex_bunload', + command = 'bwipeout', + flags = bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, TRLBAR), + addr_type = 'ADDR_BUFFERS', + func = 'ex_bunload', }, { - command='change', - flags=bit.bor(BANG, WHOLEFOLD, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_change', + command = 'change', + flags = bit.bor(BANG, WHOLEFOLD, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_change', }, { - command='cNext', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'cNext', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='cNfile', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'cNfile', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='cabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'cabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='cabclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abclear', + command = 'cabclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abclear', }, { - command='cabove', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'cabove', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='caddbuffer', - flags=bit.bor(RANGE, WORD1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cbuffer', + command = 'caddbuffer', + flags = bit.bor(RANGE, WORD1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cbuffer', }, { - command='caddexpr', - flags=bit.bor(NEEDARG, WORD1, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_cexpr', + command = 'caddexpr', + flags = bit.bor(NEEDARG, WORD1, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_cexpr', }, { - command='caddfile', - flags=bit.bor(TRLBAR, FILE1), - addr_type='ADDR_NONE', - func='ex_cfile', + command = 'caddfile', + flags = bit.bor(TRLBAR, FILE1), + addr_type = 'ADDR_NONE', + func = 'ex_cfile', }, { - command='cafter', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'cafter', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='call', - flags=bit.bor(RANGE, NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_call', + command = 'call', + flags = bit.bor(RANGE, NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_call', }, { - command='catch', - flags=bit.bor(EXTRA, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_catch', + command = 'catch', + flags = bit.bor(EXTRA, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_catch', }, { - command='cbuffer', - flags=bit.bor(BANG, RANGE, WORD1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cbuffer', + command = 'cbuffer', + flags = bit.bor(BANG, RANGE, WORD1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cbuffer', }, { - command='cbefore', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'cbefore', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='cbelow', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'cbelow', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='cbottom', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_cbottom', + command = 'cbottom', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_cbottom', }, { - command='cc', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_QUICKFIX', - func='ex_cc', + command = 'cc', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_QUICKFIX', + func = 'ex_cc', }, { - command='cclose', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_cclose', + command = 'cclose', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_cclose', }, { - command='cd', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_cd', + command = 'cd', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_cd', }, { - command='cdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_QUICKFIX_VALID', - func='ex_listdo', + command = 'cdo', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_QUICKFIX_VALID', + func = 'ex_listdo', }, { - command='center', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_align', + command = 'center', + flags = bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_align', }, { - command='cexpr', - flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, BANG), - addr_type='ADDR_NONE', - func='ex_cexpr', + command = 'cexpr', + flags = bit.bor(NEEDARG, WORD1, NOTRLCOM, BANG), + addr_type = 'ADDR_NONE', + func = 'ex_cexpr', }, { - command='cfile', - flags=bit.bor(TRLBAR, FILE1, BANG), - addr_type='ADDR_NONE', - func='ex_cfile', + command = 'cfile', + flags = bit.bor(TRLBAR, FILE1, BANG), + addr_type = 'ADDR_NONE', + func = 'ex_cfile', }, -- Even though 'cfdo' is alphabetically lower than 'cfile', it is after -- 'cfile' in this cmd list to support the existing ":cf" abbreviation. { - command='cfdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_QUICKFIX_VALID', - func='ex_listdo', + command = 'cfdo', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_QUICKFIX_VALID', + func = 'ex_listdo', }, { - command='cfirst', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cc', + command = 'cfirst', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cc', }, { - command='cgetfile', - flags=bit.bor(TRLBAR, FILE1), - addr_type='ADDR_NONE', - func='ex_cfile', + command = 'cgetfile', + flags = bit.bor(TRLBAR, FILE1), + addr_type = 'ADDR_NONE', + func = 'ex_cfile', }, { - command='cgetbuffer', - flags=bit.bor(RANGE, WORD1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cbuffer', + command = 'cgetbuffer', + flags = bit.bor(RANGE, WORD1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cbuffer', }, { - command='cgetexpr', - flags=bit.bor(NEEDARG, WORD1, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_cexpr', + command = 'cgetexpr', + flags = bit.bor(NEEDARG, WORD1, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_cexpr', }, { - command='chdir', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_cd', + command = 'chdir', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_cd', }, { - command='changes', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_changes', + command = 'changes', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_changes', }, { - command='checkhealth', - flags=bit.bor(EXTRA, TRLBAR), - addr_type='ADDR_NONE', - func='ex_checkhealth', + command = 'checkhealth', + flags = bit.bor(EXTRA, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_checkhealth', }, { - command='checkpath', - flags=bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_checkpath', + command = 'checkpath', + flags = bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_checkpath', }, { - command='checktime', - flags=bit.bor(RANGE, BUFNAME, COUNT, EXTRA, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_checktime', + command = 'checktime', + flags = bit.bor(RANGE, BUFNAME, COUNT, EXTRA, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_checktime', }, { - command='chistory', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='qf_history', + command = 'chistory', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'qf_history', }, { - command='clist', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='qf_list', + command = 'clist', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'qf_list', }, { - command='clast', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cc', + command = 'clast', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cc', }, { - command='close', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_WINDOWS', - func='ex_close', + command = 'close', + flags = bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_WINDOWS', + func = 'ex_close', }, { - command='clearjumps', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_clearjumps', + command = 'clearjumps', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_clearjumps', }, { - command='cmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'cmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='cmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'cmapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='cmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'cmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='cnext', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'cnext', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='cnewer', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='qf_age', + command = 'cnewer', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'qf_age', }, { - command='cnfile', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'cnfile', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='cnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'cnoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='cnoreabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'cnoreabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='cnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'cnoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='copy', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_copymove', + command = 'copy', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_copymove', }, { - command='colder', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='qf_age', + command = 'colder', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'qf_age', }, { - command='colorscheme', - flags=bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_colorscheme', + command = 'colorscheme', + flags = bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_colorscheme', }, { - command='command', - flags=bit.bor(EXTRA, BANG, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_command', + command = 'command', + flags = bit.bor(EXTRA, BANG, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_command', }, { - command='comclear', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_comclear', + command = 'comclear', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_comclear', }, { - command='compiler', - flags=bit.bor(BANG, TRLBAR, WORD1, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_compiler', + command = 'compiler', + flags = bit.bor(BANG, TRLBAR, WORD1, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_compiler', }, { - command='continue', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_continue', + command = 'continue', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_continue', }, { - command='confirm', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'confirm', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='const', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_let', + command = 'const', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_let', }, { - command='copen', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_copen', + command = 'copen', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_copen', }, { - command='cprevious', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'cprevious', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='cpfile', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_OTHER', - func='ex_cnext', + command = 'cpfile', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_OTHER', + func = 'ex_cnext', }, { - command='cquit', - flags=bit.bor(RANGE, COUNT, ZEROR, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cquit', + command = 'cquit', + flags = bit.bor(RANGE, COUNT, ZEROR, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cquit', }, { - command='crewind', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cc', + command = 'crewind', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cc', }, { - command='cunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'cunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='cunabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'cunabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='cunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'cunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='cwindow', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cwindow', + command = 'cwindow', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cwindow', }, { - command='delete', - flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_operators', + command = 'delete', + flags = bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_operators', }, { - command='delmarks', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_delmarks', + command = 'delmarks', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_delmarks', }, { - command='debug', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_debug', + command = 'debug', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_debug', }, { - command='debuggreedy', - flags=bit.bor(RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_debuggreedy', + command = 'debuggreedy', + flags = bit.bor(RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_debuggreedy', }, { - command='defer', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_call', + command = 'defer', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_call', }, { - command='delcommand', - flags=bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_delcommand', + command = 'delcommand', + flags = bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_delcommand', }, { - command='delfunction', - flags=bit.bor(BANG, NEEDARG, WORD1, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_delfunction', + command = 'delfunction', + flags = bit.bor(BANG, NEEDARG, WORD1, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_delfunction', }, { - command='display', - flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_display', + command = 'display', + flags = bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_display', }, { - command='diffupdate', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_diffupdate', + command = 'diffupdate', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_diffupdate', }, { - command='diffget', - flags=bit.bor(RANGE, EXTRA, TRLBAR, MODIFY), - addr_type='ADDR_LINES', - func='ex_diffgetput', + command = 'diffget', + flags = bit.bor(RANGE, EXTRA, TRLBAR, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_diffgetput', }, { - command='diffoff', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_diffoff', + command = 'diffoff', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_diffoff', }, { - command='diffpatch', - flags=bit.bor(EXTRA, FILE1, TRLBAR, MODIFY), - addr_type='ADDR_NONE', - func='ex_diffpatch', + command = 'diffpatch', + flags = bit.bor(EXTRA, FILE1, TRLBAR, MODIFY), + addr_type = 'ADDR_NONE', + func = 'ex_diffpatch', }, { - command='diffput', - flags=bit.bor(RANGE, EXTRA, TRLBAR), - addr_type='ADDR_LINES', - func='ex_diffgetput', + command = 'diffput', + flags = bit.bor(RANGE, EXTRA, TRLBAR), + addr_type = 'ADDR_LINES', + func = 'ex_diffgetput', }, { - command='diffsplit', - flags=bit.bor(EXTRA, FILE1, TRLBAR), - addr_type='ADDR_NONE', - func='ex_diffsplit', + command = 'diffsplit', + flags = bit.bor(EXTRA, FILE1, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_diffsplit', }, { - command='diffthis', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_diffthis', + command = 'diffthis', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_diffthis', }, { - command='digraphs', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_digraphs', + command = 'digraphs', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_digraphs', }, { - command='djump', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'djump', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='dlist', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'dlist', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='doautocmd', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_doautocmd', + command = 'doautocmd', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_doautocmd', }, { - command='doautoall', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_doautoall', + command = 'doautoall', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_doautoall', }, { - command='drop', - flags=bit.bor(FILES, CMDARG, NEEDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_drop', + command = 'drop', + flags = bit.bor(FILES, CMDARG, NEEDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_drop', }, { - command='dsearch', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'dsearch', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='dsplit', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'dsplit', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='edit', - flags=bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'edit', + flags = bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='earlier', - flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_later', + command = 'earlier', + flags = bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_later', }, { - command='echo', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_echo', + command = 'echo', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_echo', }, { - command='echoerr', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_execute', + command = 'echoerr', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_execute', }, { - command='echohl', - flags=bit.bor(EXTRA, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_echohl', + command = 'echohl', + flags = bit.bor(EXTRA, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_echohl', }, { - command='echomsg', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_execute', + command = 'echomsg', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_execute', }, { - command='echon', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_echo', + command = 'echon', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_echo', }, { - command='else', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_else', + command = 'else', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_else', }, { - command='elseif', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_else', + command = 'elseif', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_else', }, { - command='emenu', - flags=bit.bor(NEEDARG, EXTRA, TRLBAR, NOTRLCOM, RANGE, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_emenu', + command = 'emenu', + flags = bit.bor(NEEDARG, EXTRA, TRLBAR, NOTRLCOM, RANGE, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_emenu', }, { - command='endif', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_endif', + command = 'endif', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_endif', }, { - command='endfunction', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_endfunction', + command = 'endfunction', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_endfunction', }, { - command='endfor', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_endwhile', + command = 'endfor', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_endwhile', }, { - command='endtry', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_endtry', + command = 'endtry', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_endtry', }, { - command='endwhile', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_endwhile', + command = 'endwhile', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_endwhile', }, { - command='enew', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'enew', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='eval', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_eval', + command = 'eval', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_eval', }, { - command='ex', - flags=bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'ex', + flags = bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='execute', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_execute', + command = 'execute', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_execute', }, { - command='exit', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_exit', + command = 'exit', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_exit', }, { - command='exusage', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_exusage', + command = 'exusage', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_exusage', }, { - command='file', - flags=bit.bor(RANGE, ZEROR, BANG, FILE1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_file', + command = 'file', + flags = bit.bor(RANGE, ZEROR, BANG, FILE1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_file', }, { - command='files', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='buflist_list', + command = 'files', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'buflist_list', }, { - command='filetype', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_filetype', + command = 'filetype', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_filetype', }, { - command='filter', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'filter', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='find', - flags=bit.bor(RANGE, BANG, FILE1, CMDARG, ARGOPT, TRLBAR, NEEDARG), - addr_type='ADDR_OTHER', - func='ex_find', + command = 'find', + flags = bit.bor(RANGE, BANG, FILE1, CMDARG, ARGOPT, TRLBAR, NEEDARG), + addr_type = 'ADDR_OTHER', + func = 'ex_find', }, { - command='finally', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_finally', + command = 'finally', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_finally', }, { - command='finish', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_finish', + command = 'finish', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_finish', }, { - command='first', - flags=bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_rewind', + command = 'first', + flags = bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_rewind', }, { - command='fold', - flags=bit.bor(RANGE, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_fold', + command = 'fold', + flags = bit.bor(RANGE, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_fold', }, { - command='foldclose', - flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_foldopen', + command = 'foldclose', + flags = bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_foldopen', }, { - command='folddoopen', - flags=bit.bor(RANGE, DFLALL, NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_LINES', - func='ex_folddo', + command = 'folddoopen', + flags = bit.bor(RANGE, DFLALL, NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_LINES', + func = 'ex_folddo', }, { - command='folddoclosed', - flags=bit.bor(RANGE, DFLALL, NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_LINES', - func='ex_folddo', + command = 'folddoclosed', + flags = bit.bor(RANGE, DFLALL, NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_LINES', + func = 'ex_folddo', }, { - command='foldopen', - flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_foldopen', + command = 'foldopen', + flags = bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_foldopen', }, { - command='for', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_while', + command = 'for', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_while', }, { - command='function', - flags=bit.bor(EXTRA, BANG, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_function', + command = 'function', + flags = bit.bor(EXTRA, BANG, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_function', }, { - command='fclose', - flags=bit.bor(BANG, RANGE), - addr_type='ADDR_OTHER', - func='ex_fclose', + command = 'fclose', + flags = bit.bor(BANG, RANGE), + addr_type = 'ADDR_OTHER', + func = 'ex_fclose', }, { - command='global', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, DFLALL, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_global', + command = 'global', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, DFLALL, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_global', }, { - command='goto', - flags=bit.bor(RANGE, COUNT, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_goto', + command = 'goto', + flags = bit.bor(RANGE, COUNT, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_goto', }, { - command='grep', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_OTHER', - func='ex_make', + command = 'grep', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_OTHER', + func = 'ex_make', }, { - command='grepadd', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_OTHER', - func='ex_make', + command = 'grepadd', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_OTHER', + func = 'ex_make', }, { - command='gui', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_nogui', + command = 'gui', + flags = bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_nogui', }, { - command='gvim', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_nogui', + command = 'gvim', + flags = bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_nogui', }, { - command='help', - flags=bit.bor(BANG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_help', + command = 'help', + flags = bit.bor(BANG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_help', }, { - command='helpclose', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_helpclose', + command = 'helpclose', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_helpclose', }, { - command='helpgrep', - flags=bit.bor(EXTRA, NOTRLCOM, NEEDARG), - addr_type='ADDR_NONE', - func='ex_helpgrep', + command = 'helpgrep', + flags = bit.bor(EXTRA, NOTRLCOM, NEEDARG), + addr_type = 'ADDR_NONE', + func = 'ex_helpgrep', }, { - command='helptags', - flags=bit.bor(NEEDARG, FILES, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_helptags', + command = 'helptags', + flags = bit.bor(NEEDARG, FILES, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_helptags', }, { - command='highlight', - flags=bit.bor(BANG, EXTRA, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_highlight', + command = 'highlight', + flags = bit.bor(BANG, EXTRA, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_highlight', }, { - command='hide', - flags=bit.bor(BANG, RANGE, COUNT, EXTRA, TRLBAR), - addr_type='ADDR_WINDOWS', - func='ex_hide', + command = 'hide', + flags = bit.bor(BANG, RANGE, COUNT, EXTRA, TRLBAR), + addr_type = 'ADDR_WINDOWS', + func = 'ex_hide', }, { - command='history', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_history', + command = 'history', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_history', }, { - command='horizontal', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'horizontal', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='insert', - flags=bit.bor(BANG, RANGE, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_append', + command = 'insert', + flags = bit.bor(BANG, RANGE, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_append', }, { - command='iabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'iabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='iabclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abclear', + command = 'iabclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abclear', }, { - command='if', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_if', + command = 'if', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_if', }, { - command='ijump', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'ijump', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='ilist', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'ilist', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='imap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'imap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='imapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'imapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='imenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'imenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='inoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'inoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='inoreabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'inoreabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='inoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'inoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='intro', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_intro', + command = 'intro', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_intro', }, { - command='isearch', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'isearch', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='isplit', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), - addr_type='ADDR_LINES', - func='ex_findpat', + command = 'isplit', + flags = bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), + addr_type = 'ADDR_LINES', + func = 'ex_findpat', }, { - command='iunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'iunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='iunabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'iunabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='iunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'iunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='join', - flags=bit.bor(BANG, RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_join', + command = 'join', + flags = bit.bor(BANG, RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_join', }, { - command='jumps', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_jumps', + command = 'jumps', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_jumps', }, { - command='k', - flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_mark', + command = 'k', + flags = bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_mark', }, { - command='keepmarks', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'keepmarks', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='keepjumps', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'keepjumps', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='keeppatterns', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'keeppatterns', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='keepalt', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'keepalt', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='list', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_print', + command = 'list', + flags = bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_print', }, { - command='lNext', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'lNext', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='lNfile', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'lNfile', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='last', - flags=bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_last', + command = 'last', + flags = bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_last', }, { - command='labove', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'labove', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='language', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_language', + command = 'language', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_language', }, { - command='laddexpr', - flags=bit.bor(NEEDARG, WORD1, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_cexpr', + command = 'laddexpr', + flags = bit.bor(NEEDARG, WORD1, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_cexpr', }, { - command='laddbuffer', - flags=bit.bor(RANGE, WORD1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cbuffer', + command = 'laddbuffer', + flags = bit.bor(RANGE, WORD1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cbuffer', }, { - command='laddfile', - flags=bit.bor(TRLBAR, FILE1), - addr_type='ADDR_NONE', - func='ex_cfile', + command = 'laddfile', + flags = bit.bor(TRLBAR, FILE1), + addr_type = 'ADDR_NONE', + func = 'ex_cfile', }, { - command='lafter', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'lafter', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='later', - flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_later', + command = 'later', + flags = bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_later', }, { - command='lbuffer', - flags=bit.bor(BANG, RANGE, WORD1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cbuffer', + command = 'lbuffer', + flags = bit.bor(BANG, RANGE, WORD1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cbuffer', }, { - command='lbefore', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'lbefore', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='lbelow', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='ex_cbelow', + command = 'lbelow', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cbelow', }, { - command='lbottom', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_cbottom', + command = 'lbottom', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_cbottom', }, { - command='lcd', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_cd', + command = 'lcd', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_cd', }, { - command='lchdir', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_cd', + command = 'lchdir', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_cd', }, { - command='lclose', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cclose', + command = 'lclose', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cclose', }, { - command='ldo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_QUICKFIX_VALID', - func='ex_listdo', + command = 'ldo', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_QUICKFIX_VALID', + func = 'ex_listdo', }, { - command='left', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_align', + command = 'left', + flags = bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_align', }, { - command='leftabove', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'leftabove', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='let', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_let', + command = 'let', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_let', }, { - command='lexpr', - flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, BANG), - addr_type='ADDR_NONE', - func='ex_cexpr', + command = 'lexpr', + flags = bit.bor(NEEDARG, WORD1, NOTRLCOM, BANG), + addr_type = 'ADDR_NONE', + func = 'ex_cexpr', }, { - command='lfile', - flags=bit.bor(TRLBAR, FILE1, BANG), - addr_type='ADDR_NONE', - func='ex_cfile', + command = 'lfile', + flags = bit.bor(TRLBAR, FILE1, BANG), + addr_type = 'ADDR_NONE', + func = 'ex_cfile', }, -- Even though 'lfdo' is alphabetically lower than 'lfile', it is after -- 'lfile' in this cmd list to support the existing ":lf" abbreviation. { - command='lfdo', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_QUICKFIX_VALID', - func='ex_listdo', + command = 'lfdo', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_QUICKFIX_VALID', + func = 'ex_listdo', }, { - command='lfirst', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cc', + command = 'lfirst', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cc', }, { - command='lgetfile', - flags=bit.bor(TRLBAR, FILE1), - addr_type='ADDR_NONE', - func='ex_cfile', + command = 'lgetfile', + flags = bit.bor(TRLBAR, FILE1), + addr_type = 'ADDR_NONE', + func = 'ex_cfile', }, { - command='lgetbuffer', - flags=bit.bor(RANGE, WORD1, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cbuffer', + command = 'lgetbuffer', + flags = bit.bor(RANGE, WORD1, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cbuffer', }, { - command='lgetexpr', - flags=bit.bor(NEEDARG, WORD1, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_cexpr', + command = 'lgetexpr', + flags = bit.bor(NEEDARG, WORD1, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_cexpr', }, { - command='lgrep', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_OTHER', - func='ex_make', + command = 'lgrep', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_OTHER', + func = 'ex_make', }, { - command='lgrepadd', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_OTHER', - func='ex_make', + command = 'lgrepadd', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_OTHER', + func = 'ex_make', }, { - command='lhelpgrep', - flags=bit.bor(EXTRA, NOTRLCOM, NEEDARG), - addr_type='ADDR_NONE', - func='ex_helpgrep', + command = 'lhelpgrep', + flags = bit.bor(EXTRA, NOTRLCOM, NEEDARG), + addr_type = 'ADDR_NONE', + func = 'ex_helpgrep', }, { - command='lhistory', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='qf_history', + command = 'lhistory', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'qf_history', }, { - command='ll', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_QUICKFIX', - func='ex_cc', + command = 'll', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_QUICKFIX', + func = 'ex_cc', }, { - command='llast', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cc', + command = 'llast', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cc', }, { - command='llist', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='qf_list', + command = 'llist', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'qf_list', }, { - command='lmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'lmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='lmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'lmapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='lmake', - flags=bit.bor(BANG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_NONE', - func='ex_make', + command = 'lmake', + flags = bit.bor(BANG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_NONE', + func = 'ex_make', }, { - command='lnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'lnoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='lnext', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'lnext', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='lnewer', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='qf_age', + command = 'lnewer', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'qf_age', }, { - command='lnfile', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'lnfile', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='loadview', - flags=bit.bor(FILE1, TRLBAR), - addr_type='ADDR_NONE', - func='ex_loadview', + command = 'loadview', + flags = bit.bor(FILE1, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_loadview', }, { - command='loadkeymap', - flags=bit.bor(CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_loadkeymap', + command = 'loadkeymap', + flags = bit.bor(CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_loadkeymap', }, { - command='lockmarks', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'lockmarks', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='lockvar', - flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_lockvar', + command = 'lockvar', + flags = bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_lockvar', }, { - command='lolder', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_UNSIGNED', - func='qf_age', + command = 'lolder', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_UNSIGNED', + func = 'qf_age', }, { - command='lopen', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_copen', + command = 'lopen', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_copen', }, { - command='lprevious', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cnext', + command = 'lprevious', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cnext', }, { - command='lpfile', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_OTHER', - func='ex_cnext', + command = 'lpfile', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_OTHER', + func = 'ex_cnext', }, { - command='lrewind', - flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), - addr_type='ADDR_UNSIGNED', - func='ex_cc', + command = 'lrewind', + flags = bit.bor(RANGE, COUNT, TRLBAR, BANG), + addr_type = 'ADDR_UNSIGNED', + func = 'ex_cc', }, { - command='ltag', - flags=bit.bor(TRLBAR, BANG, WORD1), - addr_type='ADDR_NONE', - func='ex_tag', + command = 'ltag', + flags = bit.bor(TRLBAR, BANG, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_tag', }, { - command='lunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'lunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='lua', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_lua', + command = 'lua', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_lua', }, { - command='luado', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_luado', + command = 'luado', + flags = bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_luado', }, { - command='luafile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_luafile', + command = 'luafile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_luafile', }, { - command='lvimgrep', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_vimgrep', + command = 'lvimgrep', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_vimgrep', }, { - command='lvimgrepadd', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_vimgrep', + command = 'lvimgrepadd', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_vimgrep', }, { - command='lwindow', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_cwindow', + command = 'lwindow', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_cwindow', }, { - command='ls', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='buflist_list', + command = 'ls', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'buflist_list', }, { - command='move', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_copymove', + command = 'move', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_copymove', }, { - command='mark', - flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_mark', + command = 'mark', + flags = bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_mark', }, { - command='make', - flags=bit.bor(BANG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_NONE', - func='ex_make', + command = 'make', + flags = bit.bor(BANG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_NONE', + func = 'ex_make', }, { - command='map', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'map', + flags = bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='mapclear', - flags=bit.bor(EXTRA, BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'mapclear', + flags = bit.bor(EXTRA, BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='marks', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_marks', + command = 'marks', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_marks', }, { - command='match', - flags=bit.bor(RANGE, EXTRA, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_match', + command = 'match', + flags = bit.bor(RANGE, EXTRA, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_match', }, { - command='menu', - flags=bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'menu', + flags = bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='menutranslate', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menutranslate', + command = 'menutranslate', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menutranslate', }, { - command='messages', - flags=bit.bor(EXTRA, TRLBAR, RANGE, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_messages', + command = 'messages', + flags = bit.bor(EXTRA, TRLBAR, RANGE, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_messages', }, { - command='mkexrc', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mkrc', + command = 'mkexrc', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mkrc', }, { - command='mksession', - flags=bit.bor(BANG, FILE1, TRLBAR), - addr_type='ADDR_NONE', - func='ex_mkrc', + command = 'mksession', + flags = bit.bor(BANG, FILE1, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_mkrc', }, { - command='mkspell', - flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), - addr_type='ADDR_NONE', - func='ex_mkspell', + command = 'mkspell', + flags = bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + addr_type = 'ADDR_NONE', + func = 'ex_mkspell', }, { - command='mkvimrc', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mkrc', + command = 'mkvimrc', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mkrc', }, { - command='mkview', - flags=bit.bor(BANG, FILE1, TRLBAR), - addr_type='ADDR_NONE', - func='ex_mkrc', + command = 'mkview', + flags = bit.bor(BANG, FILE1, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_mkrc', }, { - command='mode', - flags=bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mode', + command = 'mode', + flags = bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mode', }, { - command='mzscheme', - flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, LOCK_OK, SBOXOK), - addr_type='ADDR_LINES', - func='ex_script_ni', + command = 'mzscheme', + flags = bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, LOCK_OK, SBOXOK), + addr_type = 'ADDR_LINES', + func = 'ex_script_ni', }, { - command='mzfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_ni', + command = 'mzfile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_ni', }, { - command='next', - flags=bit.bor(RANGE, BANG, FILES, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_next', + command = 'next', + flags = bit.bor(RANGE, BANG, FILES, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_next', }, { - command='new', - flags=bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_splitview', + command = 'new', + flags = bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_splitview', }, { - command='nmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'nmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='nmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'nmapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='nmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'nmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='nnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'nnoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='nnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'nnoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='noremap', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'noremap', + flags = bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='noautocmd', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'noautocmd', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='nohlsearch', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_nohlsearch', + command = 'nohlsearch', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_nohlsearch', }, { - command='noreabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'noreabbrev', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='noremenu', - flags=bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'noremenu', + flags = bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='noswapfile', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'noswapfile', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='normal', - flags=bit.bor(RANGE, BANG, EXTRA, NEEDARG, NOTRLCOM, CTRLV, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_normal', + command = 'normal', + flags = bit.bor(RANGE, BANG, EXTRA, NEEDARG, NOTRLCOM, CTRLV, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_normal', }, { - command='number', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_print', + command = 'number', + flags = bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_print', }, { - command='nunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'nunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='nunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'nunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='oldfiles', - flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_oldfiles', + command = 'oldfiles', + flags = bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_oldfiles', }, { - command='omap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'omap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='omapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'omapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='omenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'omenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='only', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR), - addr_type='ADDR_WINDOWS', - func='ex_only', + command = 'only', + flags = bit.bor(BANG, RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_WINDOWS', + func = 'ex_only', }, { - command='onoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'onoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='onoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'onoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='options', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_options', + command = 'options', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_options', }, { - command='ounmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'ounmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='ounmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'ounmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='ownsyntax', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_ownsyntax', + command = 'ownsyntax', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_ownsyntax', }, { - command='print', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, SBOXOK), - addr_type='ADDR_LINES', - func='ex_print', + command = 'print', + flags = bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, SBOXOK), + addr_type = 'ADDR_LINES', + func = 'ex_print', }, { - command='packadd', - flags=bit.bor(BANG, FILE1, NEEDARG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_packadd', + command = 'packadd', + flags = bit.bor(BANG, FILE1, NEEDARG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_packadd', }, { - command='packloadall', - flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_packloadall', + command = 'packloadall', + flags = bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_packloadall', }, { - command='pclose', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_pclose', + command = 'pclose', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_pclose', }, { - command='perl', - flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_perl', + command = 'perl', + flags = bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_perl', }, { - command='perldo', - flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_perldo', + command = 'perldo', + flags = bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_perldo', }, { - command='perlfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_perlfile', + command = 'perlfile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_perlfile', }, { - command='pedit', - flags=bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_pedit', + command = 'pedit', + flags = bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_pedit', }, { - command='pop', - flags=bit.bor(RANGE, BANG, COUNT, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'pop', + flags = bit.bor(RANGE, BANG, COUNT, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='popup', - flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_popup', + command = 'popup', + flags = bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_popup', }, { - command='ppop', - flags=bit.bor(RANGE, BANG, COUNT, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ppop', + flags = bit.bor(RANGE, BANG, COUNT, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='preserve', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_preserve', + command = 'preserve', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_preserve', }, { - command='previous', - flags=bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_previous', + command = 'previous', + flags = bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_previous', }, { - command='profile', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_profile', + command = 'profile', + flags = bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_profile', }, { - command='profdel', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_breakdel', + command = 'profdel', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_breakdel', }, { - command='psearch', - flags=bit.bor(BANG, RANGE, WHOLEFOLD, DFLALL, EXTRA), - addr_type='ADDR_LINES', - func='ex_psearch', + command = 'psearch', + flags = bit.bor(BANG, RANGE, WHOLEFOLD, DFLALL, EXTRA), + addr_type = 'ADDR_LINES', + func = 'ex_psearch', }, { - command='ptag', - flags=bit.bor(RANGE, BANG, WORD1, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ptag', + flags = bit.bor(RANGE, BANG, WORD1, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='ptNext', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ptNext', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='ptfirst', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ptfirst', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='ptjump', - flags=bit.bor(BANG, TRLBAR, WORD1), - addr_type='ADDR_NONE', - func='ex_ptag', + command = 'ptjump', + flags = bit.bor(BANG, TRLBAR, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_ptag', }, { - command='ptlast', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_ptag', + command = 'ptlast', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_ptag', }, { - command='ptnext', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ptnext', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='ptprevious', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ptprevious', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='ptrewind', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_ptag', + command = 'ptrewind', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_ptag', }, { - command='ptselect', - flags=bit.bor(BANG, TRLBAR, WORD1), - addr_type='ADDR_NONE', - func='ex_ptag', + command = 'ptselect', + flags = bit.bor(BANG, TRLBAR, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_ptag', }, { - command='put', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, REGSTR, TRLBAR, ZEROR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_put', + command = 'put', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, REGSTR, TRLBAR, ZEROR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_put', }, { - command='pwd', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_pwd', + command = 'pwd', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_pwd', }, { - command='python', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_python3', + command = 'python', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_python3', }, { - command='pydo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_pydo3', + command = 'pydo', + flags = bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_pydo3', }, { - command='pyfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_py3file', + command = 'pyfile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_py3file', }, { - command='py3', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_python3', + command = 'py3', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_python3', }, { - command='py3do', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_pydo3', + command = 'py3do', + flags = bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_pydo3', }, { - command='python3', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_python3', + command = 'python3', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_python3', }, { - command='py3file', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_py3file', + command = 'py3file', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_py3file', }, { - command='pyx', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_python3', + command = 'pyx', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_python3', }, { - command='pyxdo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_pydo3', + command = 'pyxdo', + flags = bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_pydo3', }, { - command='pythonx', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_python3', + command = 'pythonx', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_python3', }, { - command='pyxfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_py3file', + command = 'pyxfile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_py3file', }, { - command='quit', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_WINDOWS', - func='ex_quit', + command = 'quit', + flags = bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_WINDOWS', + func = 'ex_quit', }, { - command='quitall', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_quit_all', + command = 'quitall', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_quit_all', }, { - command='qall', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_quit_all', + command = 'qall', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_quit_all', }, { - command='read', - flags=bit.bor(BANG, RANGE, WHOLEFOLD, FILE1, ARGOPT, TRLBAR, ZEROR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_read', + command = 'read', + flags = bit.bor(BANG, RANGE, WHOLEFOLD, FILE1, ARGOPT, TRLBAR, ZEROR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_read', }, { - command='recover', - flags=bit.bor(BANG, FILE1, TRLBAR), - addr_type='ADDR_NONE', - func='ex_recover', + command = 'recover', + flags = bit.bor(BANG, FILE1, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_recover', }, { - command='redo', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_redo', + command = 'redo', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_redo', }, { - command='redir', - flags=bit.bor(BANG, FILES, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_redir', + command = 'redir', + flags = bit.bor(BANG, FILES, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_redir', }, { - command='redraw', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_redraw', + command = 'redraw', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_redraw', }, { - command='redrawstatus', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_redrawstatus', + command = 'redrawstatus', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_redrawstatus', }, { - command='redrawtabline', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_redrawtabline', + command = 'redrawtabline', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_redrawtabline', }, { - command='registers', - flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_display', + command = 'registers', + flags = bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_display', }, { - command='resize', - flags=bit.bor(RANGE, TRLBAR, WORD1, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_resize', + command = 'resize', + flags = bit.bor(RANGE, TRLBAR, WORD1, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_resize', }, { - command='retab', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, DFLALL, BANG, WORD1, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_retab', + command = 'retab', + flags = bit.bor(TRLBAR, RANGE, WHOLEFOLD, DFLALL, BANG, WORD1, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_retab', }, { - command='return', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_return', + command = 'return', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_return', }, { - command='rewind', - flags=bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_rewind', + command = 'rewind', + flags = bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_rewind', }, { - command='right', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_align', + command = 'right', + flags = bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_align', }, { - command='rightbelow', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'rightbelow', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='rshada', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_shada', + command = 'rshada', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_shada', }, { - command='runtime', - flags=bit.bor(BANG, NEEDARG, FILES, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_runtime', + command = 'runtime', + flags = bit.bor(BANG, NEEDARG, FILES, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_runtime', }, { - command='rundo', - flags=bit.bor(NEEDARG, FILE1), - addr_type='ADDR_NONE', - func='ex_rundo', + command = 'rundo', + flags = bit.bor(NEEDARG, FILE1), + addr_type = 'ADDR_NONE', + func = 'ex_rundo', }, { - command='ruby', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_ruby', + command = 'ruby', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_ruby', }, { - command='rubydo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_rubydo', + command = 'rubydo', + flags = bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_rubydo', }, { - command='rubyfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_rubyfile', + command = 'rubyfile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_rubyfile', }, { - command='rviminfo', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_shada', + command = 'rviminfo', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_shada', }, { - command='substitute', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), - addr_type='ADDR_LINES', - func='ex_substitute', - preview_func='ex_substitute_preview', + command = 'substitute', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), + addr_type = 'ADDR_LINES', + func = 'ex_substitute', + preview_func = 'ex_substitute_preview', }, { - command='sNext', - flags=bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_previous', + command = 'sNext', + flags = bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_previous', }, { - command='sargument', - flags=bit.bor(BANG, RANGE, COUNT, EXTRA, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_ARGUMENTS', - func='ex_argument', + command = 'sargument', + flags = bit.bor(BANG, RANGE, COUNT, EXTRA, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_ARGUMENTS', + func = 'ex_argument', }, { - command='sall', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_all', + command = 'sall', + flags = bit.bor(BANG, RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_all', }, { - command='sandbox', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'sandbox', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='saveas', - flags=bit.bor(BANG, FILE1, ARGOPT, CMDWIN, LOCK_OK, TRLBAR), - addr_type='ADDR_NONE', - func='ex_write', + command = 'saveas', + flags = bit.bor(BANG, FILE1, ARGOPT, CMDWIN, LOCK_OK, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_write', }, { - command='sbuffer', - flags=bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, CMDARG, TRLBAR), - addr_type='ADDR_BUFFERS', - func='ex_buffer', + command = 'sbuffer', + flags = bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, CMDARG, TRLBAR), + addr_type = 'ADDR_BUFFERS', + func = 'ex_buffer', }, { - command='sbNext', - flags=bit.bor(RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bprevious', + command = 'sbNext', + flags = bit.bor(RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bprevious', }, { - command='sball', - flags=bit.bor(RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_buffer_all', + command = 'sball', + flags = bit.bor(RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_buffer_all', }, { - command='sbfirst', - flags=bit.bor(CMDARG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_brewind', + command = 'sbfirst', + flags = bit.bor(CMDARG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_brewind', }, { - command='sblast', - flags=bit.bor(CMDARG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_blast', + command = 'sblast', + flags = bit.bor(CMDARG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_blast', }, { - command='sbmodified', - flags=bit.bor(RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bmodified', + command = 'sbmodified', + flags = bit.bor(RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bmodified', }, { - command='sbnext', - flags=bit.bor(RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bnext', + command = 'sbnext', + flags = bit.bor(RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bnext', }, { - command='sbprevious', - flags=bit.bor(RANGE, COUNT, CMDARG, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_bprevious', + command = 'sbprevious', + flags = bit.bor(RANGE, COUNT, CMDARG, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_bprevious', }, { - command='sbrewind', - flags=bit.bor(CMDARG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_brewind', + command = 'sbrewind', + flags = bit.bor(CMDARG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_brewind', }, { - command='scriptnames', - flags=bit.bor(BANG, FILES, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_scriptnames', + command = 'scriptnames', + flags = bit.bor(BANG, FILES, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_scriptnames', }, { - command='scriptencoding', - flags=bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_scriptencoding', + command = 'scriptencoding', + flags = bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_scriptencoding', }, { - command='set', - flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), - addr_type='ADDR_NONE', - func='ex_set', + command = 'set', + flags = bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), + addr_type = 'ADDR_NONE', + func = 'ex_set', }, { - command='setfiletype', - flags=bit.bor(TRLBAR, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_setfiletype', + command = 'setfiletype', + flags = bit.bor(TRLBAR, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_setfiletype', }, { - command='setglobal', - flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), - addr_type='ADDR_NONE', - func='ex_set', + command = 'setglobal', + flags = bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), + addr_type = 'ADDR_NONE', + func = 'ex_set', }, { - command='setlocal', - flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), - addr_type='ADDR_NONE', - func='ex_set', + command = 'setlocal', + flags = bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), + addr_type = 'ADDR_NONE', + func = 'ex_set', }, { - command='sfind', - flags=bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR, NEEDARG), - addr_type='ADDR_OTHER', - func='ex_splitview', + command = 'sfind', + flags = bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR, NEEDARG), + addr_type = 'ADDR_OTHER', + func = 'ex_splitview', }, { - command='sfirst', - flags=bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_rewind', + command = 'sfirst', + flags = bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_rewind', }, { - command='simalt', - flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_ni', + command = 'simalt', + flags = bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_ni', }, { - command='sign', - flags=bit.bor(NEEDARG, RANGE, EXTRA, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_sign', + command = 'sign', + flags = bit.bor(NEEDARG, RANGE, EXTRA, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_sign', }, { - command='silent', - flags=bit.bor(NEEDARG, EXTRA, BANG, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'silent', + flags = bit.bor(NEEDARG, EXTRA, BANG, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='sleep', - flags=bit.bor(BANG, RANGE, COUNT, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_sleep', + command = 'sleep', + flags = bit.bor(BANG, RANGE, COUNT, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_sleep', }, { - command='slast', - flags=bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_last', + command = 'slast', + flags = bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_last', }, { - command='smagic', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), - addr_type='ADDR_LINES', - func='ex_submagic', - preview_func='ex_submagic_preview', + command = 'smagic', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), + addr_type = 'ADDR_LINES', + func = 'ex_submagic', + preview_func = 'ex_submagic_preview', }, { - command='smap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'smap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='smapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'smapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='smenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'smenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='snext', - flags=bit.bor(RANGE, BANG, FILES, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_next', + command = 'snext', + flags = bit.bor(RANGE, BANG, FILES, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_next', }, { - command='snomagic', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), - addr_type='ADDR_LINES', - func='ex_submagic', - preview_func='ex_submagic_preview', + command = 'snomagic', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), + addr_type = 'ADDR_LINES', + func = 'ex_submagic', + preview_func = 'ex_submagic_preview', }, { - command='snoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'snoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='snoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'snoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='source', - flags=bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_source', + command = 'source', + flags = bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_source', }, { - command='sort', - flags=bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, EXTRA, NOTRLCOM, MODIFY), - addr_type='ADDR_LINES', - func='ex_sort', + command = 'sort', + flags = bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, EXTRA, NOTRLCOM, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_sort', }, { - command='split', - flags=bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_splitview', + command = 'split', + flags = bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_splitview', }, { - command='spellgood', - flags=bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_spell', + command = 'spellgood', + flags = bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_spell', }, { - command='spelldump', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_spelldump', + command = 'spelldump', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_spelldump', }, { - command='spellinfo', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_spellinfo', + command = 'spellinfo', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_spellinfo', }, { - command='spellrepall', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_spellrepall', + command = 'spellrepall', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_spellrepall', }, { - command='spellrare', - flags=bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_spell', + command = 'spellrare', + flags = bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_spell', }, { - command='spellundo', - flags=bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_spell', + command = 'spellundo', + flags = bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_spell', }, { - command='spellwrong', - flags=bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_spell', + command = 'spellwrong', + flags = bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_spell', }, { - command='sprevious', - flags=bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_previous', + command = 'sprevious', + flags = bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_previous', }, { - command='srewind', - flags=bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_rewind', + command = 'srewind', + flags = bit.bor(EXTRA, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_rewind', }, { - command='stop', - flags=bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_stop', + command = 'stop', + flags = bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_stop', }, { - command='stag', - flags=bit.bor(RANGE, BANG, WORD1, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_stag', + command = 'stag', + flags = bit.bor(RANGE, BANG, WORD1, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_stag', }, { - command='startinsert', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_startinsert', + command = 'startinsert', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_startinsert', }, { - command='startgreplace', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_startinsert', + command = 'startgreplace', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_startinsert', }, { - command='startreplace', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_startinsert', + command = 'startreplace', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_startinsert', }, { - command='stopinsert', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_stopinsert', + command = 'stopinsert', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_stopinsert', }, { - command='stjump', - flags=bit.bor(BANG, TRLBAR, WORD1), - addr_type='ADDR_NONE', - func='ex_stag', + command = 'stjump', + flags = bit.bor(BANG, TRLBAR, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_stag', }, { - command='stselect', - flags=bit.bor(BANG, TRLBAR, WORD1), - addr_type='ADDR_NONE', - func='ex_stag', + command = 'stselect', + flags = bit.bor(BANG, TRLBAR, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_stag', }, { - command='sunhide', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_buffer_all', + command = 'sunhide', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_buffer_all', }, { - command='sunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'sunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='sunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'sunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='suspend', - flags=bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_stop', + command = 'suspend', + flags = bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_stop', }, { - command='sview', - flags=bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_splitview', + command = 'sview', + flags = bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_splitview', }, { - command='swapname', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_swapname', + command = 'swapname', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_swapname', }, { - command='syntax', - flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_syntax', + command = 'syntax', + flags = bit.bor(EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_syntax', }, { - command='syntime', - flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_syntime', + command = 'syntime', + flags = bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_syntime', }, { - command='syncbind', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_syncbind', + command = 'syncbind', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_syncbind', }, { - command='t', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_copymove', + command = 't', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_copymove', }, { - command='tcd', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_cd', + command = 'tcd', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_cd', }, { - command='tchdir', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_cd', + command = 'tchdir', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_cd', }, { - command='tNext', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'tNext', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='tag', - flags=bit.bor(RANGE, BANG, WORD1, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'tag', + flags = bit.bor(RANGE, BANG, WORD1, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='tags', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='do_tags', + command = 'tags', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'do_tags', }, { - command='tab', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'tab', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='tabclose', - flags=bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_TABS', - func='ex_tabclose', + command = 'tabclose', + flags = bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_TABS', + func = 'ex_tabclose', }, { - command='tabdo', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_TABS', - func='ex_listdo', + command = 'tabdo', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_TABS', + func = 'ex_listdo', }, { - command='tabedit', - flags=bit.bor(BANG, FILE1, RANGE, ZEROR, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_TABS', - func='ex_splitview', + command = 'tabedit', + flags = bit.bor(BANG, FILE1, RANGE, ZEROR, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_TABS', + func = 'ex_splitview', }, { - command='tabfind', - flags=bit.bor(BANG, FILE1, RANGE, ZEROR, CMDARG, ARGOPT, NEEDARG, TRLBAR), - addr_type='ADDR_TABS', - func='ex_splitview', + command = 'tabfind', + flags = bit.bor(BANG, FILE1, RANGE, ZEROR, CMDARG, ARGOPT, NEEDARG, TRLBAR), + addr_type = 'ADDR_TABS', + func = 'ex_splitview', }, { - command='tabfirst', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_tabnext', + command = 'tabfirst', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_tabnext', }, { - command='tabmove', - flags=bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), - addr_type='ADDR_TABS', - func='ex_tabmove', + command = 'tabmove', + flags = bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), + addr_type = 'ADDR_TABS', + func = 'ex_tabmove', }, { - command='tablast', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_tabnext', + command = 'tablast', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_tabnext', }, { - command='tabnext', - flags=bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), - addr_type='ADDR_TABS', - func='ex_tabnext', + command = 'tabnext', + flags = bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), + addr_type = 'ADDR_TABS', + func = 'ex_tabnext', }, { - command='tabnew', - flags=bit.bor(BANG, FILE1, RANGE, ZEROR, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_TABS', - func='ex_splitview', + command = 'tabnew', + flags = bit.bor(BANG, FILE1, RANGE, ZEROR, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_TABS', + func = 'ex_splitview', }, { - command='tabonly', - flags=bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_TABS', - func='ex_tabonly', + command = 'tabonly', + flags = bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_TABS', + func = 'ex_tabonly', }, { - command='tabprevious', - flags=bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), - addr_type='ADDR_TABS_RELATIVE', - func='ex_tabnext', + command = 'tabprevious', + flags = bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), + addr_type = 'ADDR_TABS_RELATIVE', + func = 'ex_tabnext', }, { - command='tabNext', - flags=bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), - addr_type='ADDR_TABS_RELATIVE', - func='ex_tabnext', + command = 'tabNext', + flags = bit.bor(RANGE, ZEROR, EXTRA, NOSPC, TRLBAR), + addr_type = 'ADDR_TABS_RELATIVE', + func = 'ex_tabnext', }, { - command='tabrewind', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_tabnext', + command = 'tabrewind', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_tabnext', }, { - command='tabs', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_tabs', + command = 'tabs', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_tabs', }, { - command='tcl', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_script_ni', + command = 'tcl', + flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_script_ni', }, { - command='tcldo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_ni', + command = 'tcldo', + flags = bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_ni', }, { - command='tclfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_ni', + command = 'tclfile', + flags = bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_ni', }, { - command='terminal', - flags=bit.bor(BANG, FILES, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_terminal', + command = 'terminal', + flags = bit.bor(BANG, FILES, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_terminal', }, { - command='tfirst', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'tfirst', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='throw', - flags=bit.bor(EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_throw', + command = 'throw', + flags = bit.bor(EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_throw', }, { - command='tjump', - flags=bit.bor(BANG, TRLBAR, WORD1), - addr_type='ADDR_NONE', - func='ex_tag', + command = 'tjump', + flags = bit.bor(BANG, TRLBAR, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_tag', }, { - command='tlast', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_tag', + command = 'tlast', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_tag', }, { - command='tlmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'tlmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='tlnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'tlnoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='tlunmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'tlunmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='tmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'tmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='tmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'tmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='tmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'tmapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='tnext', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'tnext', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='tnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'tnoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='topleft', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'topleft', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='tprevious', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'tprevious', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='trewind', - flags=bit.bor(RANGE, BANG, TRLBAR, ZEROR), - addr_type='ADDR_OTHER', - func='ex_tag', + command = 'trewind', + flags = bit.bor(RANGE, BANG, TRLBAR, ZEROR), + addr_type = 'ADDR_OTHER', + func = 'ex_tag', }, { - command='trust', - flags=bit.bor(EXTRA, FILE1, TRLBAR, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_trust', + command = 'trust', + flags = bit.bor(EXTRA, FILE1, TRLBAR, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_trust', }, { - command='try', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_try', + command = 'try', + flags = bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_try', }, { - command='tselect', - flags=bit.bor(BANG, TRLBAR, WORD1), - addr_type='ADDR_NONE', - func='ex_tag', + command = 'tselect', + flags = bit.bor(BANG, TRLBAR, WORD1), + addr_type = 'ADDR_NONE', + func = 'ex_tag', }, { - command='tunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'tunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='tunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'tunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='undo', - flags=bit.bor(BANG, RANGE, COUNT, ZEROR, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_undo', + command = 'undo', + flags = bit.bor(BANG, RANGE, COUNT, ZEROR, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_undo', }, { - command='undojoin', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_undojoin', + command = 'undojoin', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_undojoin', }, { - command='undolist', - flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_undolist', + command = 'undolist', + flags = bit.bor(TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_undolist', }, { - command='unabbreviate', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_abbreviate', + command = 'unabbreviate', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_abbreviate', }, { - command='unhide', - flags=bit.bor(RANGE, COUNT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_buffer_all', + command = 'unhide', + flags = bit.bor(RANGE, COUNT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_buffer_all', }, { - command='unlet', - flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unlet', + command = 'unlet', + flags = bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unlet', }, { - command='unlockvar', - flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_lockvar', + command = 'unlockvar', + flags = bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_lockvar', }, { - command='unmap', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'unmap', + flags = bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='unmenu', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'unmenu', + flags = bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='unsilent', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'unsilent', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='update', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR), - addr_type='ADDR_LINES', - func='ex_update', + command = 'update', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR), + addr_type = 'ADDR_LINES', + func = 'ex_update', }, { - command='vglobal', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, DFLALL, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_global', + command = 'vglobal', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, DFLALL, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_global', }, { - command='version', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_version', + command = 'version', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_version', }, { - command='verbose', - flags=bit.bor(NEEDARG, RANGE, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_wrongmodifier', + command = 'verbose', + flags = bit.bor(NEEDARG, RANGE, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_wrongmodifier', }, { - command='vertical', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), - addr_type='ADDR_NONE', - func='ex_wrongmodifier', + command = 'vertical', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type = 'ADDR_NONE', + func = 'ex_wrongmodifier', }, { - command='visual', - flags=bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'visual', + flags = bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='view', - flags=bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='ex_edit', + command = 'view', + flags = bit.bor(BANG, FILE1, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_edit', }, { - command='vimgrep', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_vimgrep', + command = 'vimgrep', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_vimgrep', }, { - command='vimgrepadd', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_vimgrep', + command = 'vimgrepadd', + flags = bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_vimgrep', }, { - command='viusage', - flags=bit.bor(TRLBAR), - addr_type='ADDR_NONE', - func='ex_viusage', + command = 'viusage', + flags = bit.bor(TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_viusage', }, { - command='vmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'vmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='vmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'vmapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='vmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'vmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='vnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'vnoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='vnew', - flags=bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_splitview', + command = 'vnew', + flags = bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_splitview', }, { - command='vnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'vnoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='vsplit', - flags=bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_splitview', + command = 'vsplit', + flags = bit.bor(BANG, FILE1, RANGE, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_splitview', }, { - command='vunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'vunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='vunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'vunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='write', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_write', + command = 'write', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_write', }, { - command='wNext', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_wnext', + command = 'wNext', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_wnext', }, { - command='wall', - flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='do_wqall', + command = 'wall', + flags = bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'do_wqall', }, { - command='while', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_while', + command = 'while', + flags = bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_while', }, { - command='winsize', - flags=bit.bor(EXTRA, NEEDARG, TRLBAR), - addr_type='ADDR_NONE', - func='ex_winsize', + command = 'winsize', + flags = bit.bor(EXTRA, NEEDARG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'ex_winsize', }, { - command='wincmd', - flags=bit.bor(NEEDARG, WORD1, RANGE, COUNT, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_wincmd', + command = 'wincmd', + flags = bit.bor(NEEDARG, WORD1, RANGE, COUNT, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_wincmd', }, { - command='windo', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), - addr_type='ADDR_WINDOWS', - func='ex_listdo', + command = 'windo', + flags = bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), + addr_type = 'ADDR_WINDOWS', + func = 'ex_listdo', }, { - command='winpos', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_ni', + command = 'winpos', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_ni', }, { - command='wnext', - flags=bit.bor(RANGE, BANG, FILE1, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_wnext', + command = 'wnext', + flags = bit.bor(RANGE, BANG, FILE1, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_wnext', }, { - command='wprevious', - flags=bit.bor(RANGE, BANG, FILE1, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_wnext', + command = 'wprevious', + flags = bit.bor(RANGE, BANG, FILE1, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_wnext', }, { - command='wq', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR), - addr_type='ADDR_LINES', - func='ex_exit', + command = 'wq', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR), + addr_type = 'ADDR_LINES', + func = 'ex_exit', }, { - command='wqall', - flags=bit.bor(BANG, FILE1, ARGOPT, TRLBAR), - addr_type='ADDR_NONE', - func='do_wqall', + command = 'wqall', + flags = bit.bor(BANG, FILE1, ARGOPT, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'do_wqall', }, { - command='wshada', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_shada', + command = 'wshada', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_shada', }, { - command='wundo', - flags=bit.bor(BANG, NEEDARG, FILE1), - addr_type='ADDR_NONE', - func='ex_wundo', + command = 'wundo', + flags = bit.bor(BANG, NEEDARG, FILE1), + addr_type = 'ADDR_NONE', + func = 'ex_wundo', }, { - command='wviminfo', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_shada', + command = 'wviminfo', + flags = bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_shada', }, { - command='xit', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_exit', + command = 'xit', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_exit', }, { - command='xall', - flags=bit.bor(BANG, TRLBAR), - addr_type='ADDR_NONE', - func='do_wqall', + command = 'xall', + flags = bit.bor(BANG, TRLBAR), + addr_type = 'ADDR_NONE', + func = 'do_wqall', }, { - command='xmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'xmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='xmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_mapclear', + command = 'xmapclear', + flags = bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_mapclear', }, { - command='xmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'xmenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='xnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_map', + command = 'xnoremap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_map', }, { - command='xnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_OTHER', - func='ex_menu', + command = 'xnoremenu', + flags = bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_OTHER', + func = 'ex_menu', }, { - command='xunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_unmap', + command = 'xunmap', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_unmap', }, { - command='xunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), - addr_type='ADDR_NONE', - func='ex_menu', + command = 'xunmenu', + flags = bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), + addr_type = 'ADDR_NONE', + func = 'ex_menu', }, { - command='yank', - flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_operators', + command = 'yank', + flags = bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_operators', }, { - command='z', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, FLAGS, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_z', + command = 'z', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, FLAGS, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_z', }, -- commands that don't start with a letter { - command='!', - enum='CMD_bang', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILES, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_bang', + command = '!', + enum = 'CMD_bang', + flags = bit.bor(RANGE, WHOLEFOLD, BANG, FILES, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_bang', }, { - command='#', - enum='CMD_pound', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_print', + command = '#', + enum = 'CMD_pound', + flags = bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_print', }, { - command='&', - enum='CMD_and', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_substitute', + command = '&', + enum = 'CMD_and', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_substitute', }, { - command='<', - enum='CMD_lshift', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_operators', + command = '<', + enum = 'CMD_lshift', + flags = bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_operators', }, { - command='=', - enum='CMD_equal', - flags=bit.bor(RANGE, EXTRA, DFLALL, ARGOPT, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_equal', + command = '=', + enum = 'CMD_equal', + flags = bit.bor(RANGE, EXTRA, DFLALL, ARGOPT, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_equal', }, { - command='>', - enum='CMD_rshift', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_operators', + command = '>', + enum = 'CMD_rshift', + flags = bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_operators', }, { - command='@', - enum='CMD_at', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK), - addr_type='ADDR_LINES', - func='ex_at', + command = '@', + enum = 'CMD_at', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK), + addr_type = 'ADDR_LINES', + func = 'ex_at', }, { - command='~', - enum='CMD_tilde', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), - addr_type='ADDR_LINES', - func='ex_substitute', + command = '~', + enum = 'CMD_tilde', + flags = bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), + addr_type = 'ADDR_LINES', + func = 'ex_substitute', }, -- commands that start with an uppercase letter { - command='Next', - flags=bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_previous', + command = 'Next', + flags = bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type = 'ADDR_OTHER', + func = 'ex_previous', }, } diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua index f33da452ff..1720b32919 100644 --- a/src/nvim/generators/c_grammar.lua +++ b/src/nvim/generators/c_grammar.lua @@ -17,50 +17,70 @@ local fill = ws ^ 0 local c_comment = P('//') * (not_nl ^ 0) local c_preproc = P('#') * (not_nl ^ 0) local dllexport = P('DLLEXPORT') * (ws ^ 1) -local typed_container = - (P('ArrayOf(') + P('DictionaryOf(') + P('Dict(')) * ((any - P(')')) ^ 1) * P(')') -local c_id = ( - typed_container + - (letter * (alpha ^ 0)) -) +local typed_container = (P('ArrayOf(') + P('DictionaryOf(') + P('Dict(')) + * ((any - P(')')) ^ 1) + * P(')') +local c_id = (typed_container + (letter * (alpha ^ 0))) local c_void = P('void') local c_param_type = ( - ((P('Error') * fill * P('*') * fill) * Cc('error')) + - ((P('Arena') * fill * P('*') * fill) * Cc('arena')) + - ((P('lua_State') * fill * P('*') * fill) * Cc('lstate')) + - C((P('const ') ^ -1) * (c_id) * (ws ^ 1) * P('*')) + - (C(c_id) * (ws ^ 1)) - ) + ((P('Error') * fill * P('*') * fill) * Cc('error')) + + ((P('Arena') * fill * P('*') * fill) * Cc('arena')) + + ((P('lua_State') * fill * P('*') * fill) * Cc('lstate')) + + C((P('const ') ^ -1) * c_id * (ws ^ 1) * P('*')) + + (C(c_id) * (ws ^ 1)) +) local c_type = (C(c_void) * (ws ^ 1)) + c_param_type local c_param = Ct(c_param_type * C(c_id)) local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0) local c_params = Ct(c_void + c_param_list) local c_proto = Ct( - (dllexport ^ -1) * - Cg(c_type, 'return_type') * Cg(c_id, 'name') * - fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') * - Cg(Cc(false), 'fast') * - (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) * - (fill * Cg((P('FUNC_API_DEPRECATED_SINCE(') * C(num ^ 1)) * P(')'), - 'deprecated_since') ^ -1) * - (fill * Cg((P('FUNC_API_FAST') * Cc(true)), 'fast') ^ -1) * - (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) * - (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) * - (fill * Cg((P('FUNC_API_LUA_ONLY') * Cc(true)), 'lua_only') ^ -1) * - (fill * (Cg(P('FUNC_API_TEXTLOCK_ALLOW_CMDWIN') * Cc(true), 'textlock_allow_cmdwin') + - Cg(P('FUNC_API_TEXTLOCK') * Cc(true), 'textlock')) ^ -1) * - (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) * - (fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) * - (fill * Cg((P('FUNC_API_CLIENT_IMPL') * Cc(true)), 'client_impl') ^ -1) * - (fill * Cg((P('FUNC_API_CLIENT_IGNORE') * Cc(true)), 'client_ignore') ^ -1) * - fill * P(';') - ) + (dllexport ^ -1) + * Cg(c_type, 'return_type') + * Cg(c_id, 'name') + * fill + * P('(') + * fill + * Cg(c_params, 'parameters') + * fill + * P(')') + * Cg(Cc(false), 'fast') + * (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) + * (fill * Cg((P('FUNC_API_DEPRECATED_SINCE(') * C(num ^ 1)) * P(')'), 'deprecated_since') ^ -1) + * (fill * Cg((P('FUNC_API_FAST') * Cc(true)), 'fast') ^ -1) + * (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) + * (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) + * (fill * Cg((P('FUNC_API_LUA_ONLY') * Cc(true)), 'lua_only') ^ -1) + * (fill * (Cg(P('FUNC_API_TEXTLOCK_ALLOW_CMDWIN') * Cc(true), 'textlock_allow_cmdwin') + Cg( + P('FUNC_API_TEXTLOCK') * Cc(true), + 'textlock' + )) ^ -1) + * (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) + * (fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) + * (fill * Cg((P('FUNC_API_CLIENT_IMPL') * Cc(true)), 'client_impl') ^ -1) + * (fill * Cg((P('FUNC_API_CLIENT_IGNORE') * Cc(true)), 'client_ignore') ^ -1) + * fill + * P(';') +) local c_field = Ct(Cg(c_id, 'type') * ws * Cg(c_id, 'name') * fill * P(';') * fill) local c_keyset = Ct( - P('typedef') * ws * P('struct') * fill * P('{') * fill * - Cg(Ct(c_field ^ 1), 'fields') * - P('}') * fill * P('Dict') * fill * P('(') * Cg(c_id, 'keyset_name') * fill * P(')') * P(';')) + P('typedef') + * ws + * P('struct') + * fill + * P('{') + * fill + * Cg(Ct(c_field ^ 1), 'fields') + * P('}') + * fill + * P('Dict') + * fill + * P('(') + * Cg(c_id, 'keyset_name') + * fill + * P(')') + * P(';') +) local grammar = Ct((c_proto + c_comment + c_preproc + ws + c_keyset) ^ 1) -return {grammar=grammar, typed_container=typed_container} +return { grammar = grammar, typed_container = typed_container } diff --git a/src/nvim/generators/dump_bin_array.lua b/src/nvim/generators/dump_bin_array.lua index bee5aba73f..c6cda25e73 100644 --- a/src/nvim/generators/dump_bin_array.lua +++ b/src/nvim/generators/dump_bin_array.lua @@ -1,10 +1,10 @@ local function dump_bin_array(output, name, data) output:write([[ - static const uint8_t ]]..name..[[[] = { + static const uint8_t ]] .. name .. [[[] = { ]]) for i = 1, #data do - output:write(string.byte(data, i)..', ') + output:write(string.byte(data, i) .. ', ') if i % 10 == 0 then output:write('\n ') end diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 81b5096557..7cec118243 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -1,6 +1,6 @@ local mpack = vim.mpack -local hashy = require'generators.hashy' +local hashy = require 'generators.hashy' assert(#arg >= 5) -- output h file with generated dispatch functions (dispatch_wrappers.generated.h) @@ -23,16 +23,20 @@ local function_names = {} local c_grammar = require('generators.c_grammar') -local function startswith(String,Start) - return string.sub(String,1,string.len(Start))==Start +local function startswith(String, Start) + return string.sub(String, 1, string.len(Start)) == Start end local function add_function(fn) - local public = startswith(fn.name, "nvim_") or fn.deprecated_since + local public = startswith(fn.name, 'nvim_') or fn.deprecated_since if public and not fn.noexport then functions[#functions + 1] = fn function_names[fn.name] = true - if #fn.parameters >= 2 and fn.parameters[2][1] == 'Array' and fn.parameters[2][2] == 'uidata' then + if + #fn.parameters >= 2 + and fn.parameters[2][1] == 'Array' + and fn.parameters[2][2] == 'uidata' + then -- function receives the "args" as a parameter fn.receives_array_args = true -- remove the args parameter @@ -70,7 +74,7 @@ local function add_keyset(val) local types = {} local is_set_name = 'is_set__' .. val.keyset_name .. '_' local has_optional = false - for i,field in ipairs(val.fields) do + for i, field in ipairs(val.fields) do if field.type ~= 'Object' then types[field.name] = field.type end @@ -80,14 +84,17 @@ local function add_keyset(val) if i > 1 then error("'is_set__{type}_' must be first if present") elseif field.name ~= is_set_name then - error(val.keyset_name..": name of first key should be "..is_set_name) + error(val.keyset_name .. ': name of first key should be ' .. is_set_name) elseif field.type ~= 'OptionalKeys' then - error("'"..is_set_name.."' must have type 'OptionalKeys'") + error("'" .. is_set_name .. "' must have type 'OptionalKeys'") end has_optional = true end end - table.insert(keysets, {name=val.keyset_name, keys=keys, types=types, has_optional=has_optional}) + table.insert( + keysets, + { name = val.keyset_name, keys = keys, types = types, has_optional = has_optional } + ) end -- read each input file, parse and append to the api metadata @@ -97,7 +104,7 @@ for i = 6, #arg do for part in string.gmatch(full_path, '[^/]+') do parts[#parts + 1] = part end - headers[#headers + 1] = parts[#parts - 1]..'/'..parts[#parts] + headers[#headers + 1] = parts[#parts - 1] .. '/' .. parts[#parts] local input = io.open(full_path, 'rb') @@ -123,14 +130,14 @@ end -- Export functions under older deprecated names. -- These will be removed eventually. -local deprecated_aliases = require("api.dispatch_deprecated") -for _,f in ipairs(shallowcopy(functions)) do +local deprecated_aliases = require('api.dispatch_deprecated') +for _, f in ipairs(shallowcopy(functions)) do local ismethod = false - if startswith(f.name, "nvim_") then - if startswith(f.name, "nvim__") or f.name == "nvim_error_event" then + if startswith(f.name, 'nvim_') then + if startswith(f.name, 'nvim__') or f.name == 'nvim_error_event' then f.since = -1 elseif f.since == nil then - print("Function "..f.name.." lacks since field.\n") + print('Function ' .. f.name .. ' lacks since field.\n') os.exit(1) end f.since = tonumber(f.since) @@ -138,16 +145,16 @@ for _,f in ipairs(shallowcopy(functions)) do f.deprecated_since = tonumber(f.deprecated_since) end - if startswith(f.name, "nvim_buf_") then + if startswith(f.name, 'nvim_buf_') then ismethod = true - elseif startswith(f.name, "nvim_win_") then + elseif startswith(f.name, 'nvim_win_') then ismethod = true - elseif startswith(f.name, "nvim_tabpage_") then + elseif startswith(f.name, 'nvim_tabpage_') then ismethod = true end f.remote = f.remote_only or not f.lua_only f.lua = f.lua_only or not f.remote_only - f.eval = (not f.lua_only) and (not f.remote_only) + f.eval = (not f.lua_only) and not f.remote_only else f.deprecated_since = tonumber(f.deprecated_since) assert(f.deprecated_since == 1) @@ -159,56 +166,59 @@ for _,f in ipairs(shallowcopy(functions)) do if newname ~= nil then if function_names[newname] then -- duplicate - print("Function "..f.name.." has deprecated alias\n" - ..newname.." which has a separate implementation.\n".. - "Please remove it from src/nvim/api/dispatch_deprecated.lua") + print( + 'Function ' + .. f.name + .. ' has deprecated alias\n' + .. newname + .. ' which has a separate implementation.\n' + .. 'Please remove it from src/nvim/api/dispatch_deprecated.lua' + ) os.exit(1) end local newf = shallowcopy(f) newf.name = newname - if newname == "ui_try_resize" then + if newname == 'ui_try_resize' then -- The return type was incorrectly set to Object in 0.1.5. -- Keep it that way for clients that rely on this. - newf.return_type = "Object" + newf.return_type = 'Object' end newf.impl_name = f.name newf.lua = false newf.eval = false newf.since = 0 newf.deprecated_since = 1 - functions[#functions+1] = newf + functions[#functions + 1] = newf end end -- don't expose internal attributes like "impl_name" in public metadata -local exported_attributes = {'name', 'return_type', 'method', - 'since', 'deprecated_since'} +local exported_attributes = { 'name', 'return_type', 'method', 'since', 'deprecated_since' } local exported_functions = {} -for _,f in ipairs(functions) do - if not (startswith(f.name, "nvim__") or f.name == "nvim_error_event" or f.name == "redraw") then +for _, f in ipairs(functions) do + if not (startswith(f.name, 'nvim__') or f.name == 'nvim_error_event' or f.name == 'redraw') then local f_exported = {} - for _,attr in ipairs(exported_attributes) do + for _, attr in ipairs(exported_attributes) do f_exported[attr] = f[attr] end f_exported.parameters = {} - for i,param in ipairs(f.parameters) do - if param[1] == "DictionaryOf(LuaRef)" then - param = {"Dictionary", param[2]} - elseif startswith(param[1], "Dict(") then - param = {"Dictionary", param[2]} + for i, param in ipairs(f.parameters) do + if param[1] == 'DictionaryOf(LuaRef)' then + param = { 'Dictionary', param[2] } + elseif startswith(param[1], 'Dict(') then + param = { 'Dictionary', param[2] } end f_exported.parameters[i] = param end - exported_functions[#exported_functions+1] = f_exported + exported_functions[#exported_functions + 1] = f_exported end end - -- serialize the API metadata using msgpack and embed into the resulting -- binary for easy querying by clients local funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb') local packed = mpack.encode(exported_functions) -local dump_bin_array = require("generators.dump_bin_array") +local dump_bin_array = require('generators.dump_bin_array') dump_bin_array(funcs_metadata_output, 'funcs_metadata', packed) funcs_metadata_output:close() @@ -246,67 +256,81 @@ output:write([[ ]]) -for _,k in ipairs(keysets) do +for _, k in ipairs(keysets) do local c_name = {} - for i = 1,#k.keys do + for i = 1, #k.keys do -- some keys, like "register" are c keywords and get -- escaped with a trailing _ in the struct. - if vim.endswith(k.keys[i], "_") then + if vim.endswith(k.keys[i], '_') then local orig = k.keys[i] - k.keys[i] = string.sub(k.keys[i],1, #(k.keys[i]) - 1) + k.keys[i] = string.sub(k.keys[i], 1, #k.keys[i] - 1) c_name[k.keys[i]] = orig k.types[k.keys[i]] = k.types[orig] end end - local neworder, hashfun = hashy.hashy_hash(k.name, k.keys, function (idx) - return k.name.."_table["..idx.."].str" + local neworder, hashfun = hashy.hashy_hash(k.name, k.keys, function(idx) + return k.name .. '_table[' .. idx .. '].str' end) - keysets_defs:write("extern KeySetLink "..k.name.."_table[];\n") + keysets_defs:write('extern KeySetLink ' .. k.name .. '_table[];\n') local function typename(type) if type ~= nil then - return "kObjectType"..type + return 'kObjectType' .. type else - return "kObjectTypeNil" + return 'kObjectTypeNil' end end - output:write("KeySetLink "..k.name.."_table[] = {\n") + output:write('KeySetLink ' .. k.name .. '_table[] = {\n') for i, key in ipairs(neworder) do local ind = -1 if k.has_optional then ind = i - keysets_defs:write("#define KEYSET_OPTIDX_"..k.name.."__"..key.." "..ind.."\n") - end - output:write(' {"'..key..'", offsetof(KeyDict_'..k.name..", "..(c_name[key] or key).."), "..typename(k.types[key])..", "..ind.."},\n") + keysets_defs:write('#define KEYSET_OPTIDX_' .. k.name .. '__' .. key .. ' ' .. ind .. '\n') + end + output:write( + ' {"' + .. key + .. '", offsetof(KeyDict_' + .. k.name + .. ', ' + .. (c_name[key] or key) + .. '), ' + .. typename(k.types[key]) + .. ', ' + .. ind + .. '},\n' + ) end - output:write(' {NULL, 0, kObjectTypeNil, -1},\n') - output:write("};\n\n") + output:write(' {NULL, 0, kObjectTypeNil, -1},\n') + output:write('};\n\n') output:write(hashfun) output:write([[ -KeySetLink *KeyDict_]]..k.name..[[_get_field(const char *str, size_t len) +KeySetLink *KeyDict_]] .. k.name .. [[_get_field(const char *str, size_t len) { - int hash = ]]..k.name..[[_hash(str, len); + int hash = ]] .. k.name .. [[_hash(str, len); if (hash == -1) { return NULL; } - return &]]..k.name..[[_table[hash]; + return &]] .. k.name .. [[_table[hash]; } ]]) - keysets_defs:write("#define api_free_keydict_"..k.name.."(x) api_free_keydict(x, "..k.name.."_table)\n") + keysets_defs:write( + '#define api_free_keydict_' .. k.name .. '(x) api_free_keydict(x, ' .. k.name .. '_table)\n' + ) end local function real_type(type) local rv = type - local rmatch = string.match(type, "Dict%(([_%w]+)%)") + local rmatch = string.match(type, 'Dict%(([_%w]+)%)') if rmatch then - return "KeyDict_"..rmatch + return 'KeyDict_' .. rmatch elseif c_grammar.typed_container:match(rv) then if rv:match('Array') then rv = 'Array' @@ -333,24 +357,30 @@ for i = 1, #functions do if fn.impl_name == nil and fn.remote then local args = {} - output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Arena* arena, Error *error)') + output:write( + 'Object handle_' .. fn.name .. '(uint64_t channel_id, Array args, Arena* arena, Error *error)' + ) output:write('\n{') output:write('\n#ifdef NVIM_LOG_DEBUG') - output:write('\n DLOG("RPC: ch %" PRIu64 ": invoke '..fn.name..'", channel_id);') + output:write('\n DLOG("RPC: ch %" PRIu64 ": invoke ' .. fn.name .. '", channel_id);') output:write('\n#endif') output:write('\n Object ret = NIL;') -- Declare/initialize variables that will hold converted arguments for j = 1, #fn.parameters do local param = fn.parameters[j] local rt = real_type(param[1]) - local converted = 'arg_'..j - output:write('\n '..rt..' '..converted..';') + local converted = 'arg_' .. j + output:write('\n ' .. rt .. ' ' .. converted .. ';') end output:write('\n') if not fn.receives_array_args then - output:write('\n if (args.size != '..#fn.parameters..') {') - output:write('\n api_set_error(error, kErrorTypeException, \ - "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);') + output:write('\n if (args.size != ' .. #fn.parameters .. ') {') + output:write( + '\n api_set_error(error, kErrorTypeException, \ + "Wrong number of arguments: expecting ' + .. #fn.parameters + .. ' but got %zu", args.size);' + ) output:write('\n goto cleanup;') output:write('\n }\n') end @@ -359,55 +389,121 @@ for i = 1, #functions do for j = 1, #fn.parameters do local converted, param param = fn.parameters[j] - converted = 'arg_'..j + converted = 'arg_' .. j local rt = real_type(param[1]) if rt == 'Object' then - output:write('\n '..converted..' = args.items['..(j - 1)..'];\n') + output:write('\n ' .. converted .. ' = args.items[' .. (j - 1) .. '];\n') elseif rt:match('^KeyDict_') then converted = '&' .. converted - output:write('\n if (args.items['..(j - 1)..'].type == kObjectTypeDictionary) {') --luacheck: ignore 631 - output:write('\n memset('..converted..', 0, sizeof(*'..converted..'));') -- TODO: neeeee - output:write('\n if (!api_dict_to_keydict('..converted..', '..rt..'_get_field, args.items['..(j - 1)..'].data.dictionary, error)) {') + output:write('\n if (args.items[' .. (j - 1) .. '].type == kObjectTypeDictionary) {') --luacheck: ignore 631 + output:write('\n memset(' .. converted .. ', 0, sizeof(*' .. converted .. '));') -- TODO: neeeee + output:write( + '\n if (!api_dict_to_keydict(' + .. converted + .. ', ' + .. rt + .. '_get_field, args.items[' + .. (j - 1) + .. '].data.dictionary, error)) {' + ) output:write('\n goto cleanup;') output:write('\n }') - 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 memset('..converted..', 0, sizeof(*'..converted..'));') + 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 memset(' .. converted .. ', 0, sizeof(*' .. converted .. '));') output:write('\n } else {') - output:write('\n api_set_error(error, kErrorTypeException, \ - "Wrong type for argument '..j..' when calling '..fn.name..', expecting '..param[1]..'");') + output:write( + '\n api_set_error(error, kErrorTypeException, \ + "Wrong type for argument ' + .. j + .. ' when calling ' + .. fn.name + .. ', expecting ' + .. param[1] + .. '");' + ) output:write('\n goto cleanup;') output:write('\n }\n') else if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') then -- Buffer, Window, and Tabpage have a specific type, but are stored in integer - output:write('\n if (args.items['.. - (j - 1)..'].type == kObjectType'..rt..' && args.items['..(j - 1)..'].data.integer >= 0) {') - output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;') + output:write( + '\n if (args.items[' + .. (j - 1) + .. '].type == kObjectType' + .. rt + .. ' && args.items[' + .. (j - 1) + .. '].data.integer >= 0) {' + ) + output:write( + '\n ' .. converted .. ' = (handle_T)args.items[' .. (j - 1) .. '].data.integer;' + ) else - output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {') - output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..attr_name(rt)..';') + output:write('\n if (args.items[' .. (j - 1) .. '].type == kObjectType' .. rt .. ') {') + output:write( + '\n ' + .. converted + .. ' = args.items[' + .. (j - 1) + .. '].data.' + .. attr_name(rt) + .. ';' + ) end - if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then + if + rt:match('^Buffer$') + or rt:match('^Window$') + or rt:match('^Tabpage$') + or rt:match('^Boolean$') + then -- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages - output:write('\n } else if (args.items['.. - (j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {') - output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;') + output:write( + '\n } else if (args.items[' + .. (j - 1) + .. '].type == kObjectTypeInteger && args.items[' + .. (j - 1) + .. '].data.integer >= 0) {' + ) + output:write( + '\n ' .. converted .. ' = (handle_T)args.items[' .. (j - 1) .. '].data.integer;' + ) end if rt:match('^Float$') then -- accept integers for Floats - output:write('\n } else if (args.items['.. - (j - 1)..'].type == kObjectTypeInteger) {') - output:write('\n '..converted..' = (Float)args.items['..(j - 1)..'].data.integer;') + output:write('\n } else if (args.items[' .. (j - 1) .. '].type == kObjectTypeInteger) {') + output:write( + '\n ' .. converted .. ' = (Float)args.items[' .. (j - 1) .. '].data.integer;' + ) end -- 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;') + 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;') end output:write('\n } else {') - output:write('\n api_set_error(error, kErrorTypeException, \ - "Wrong type for argument '..j..' when calling '..fn.name..', expecting '..param[1]..'");') + output:write( + '\n api_set_error(error, kErrorTypeException, \ + "Wrong type for argument ' + .. j + .. ' when calling ' + .. fn.name + .. ', expecting ' + .. param[1] + .. '");' + ) output:write('\n goto cleanup;') output:write('\n }\n') end @@ -431,11 +527,11 @@ for i = 1, #functions do output:write('\n ') if fn.return_type ~= 'void' then -- has a return value, prefix the call with a declaration - output:write(fn.return_type..' rv = ') + output:write(fn.return_type .. ' rv = ') end -- write the function name and the opening parenthesis - output:write(fn.name..'(') + output:write(fn.name .. '(') if fn.receives_channel_id then -- if the function receives the channel id, pass it as first argument @@ -455,7 +551,7 @@ for i = 1, #functions do else if fn.receives_array_args then if #args > 0 or fn.call_fail then - output:write('args, '..call_args) + output:write('args, ' .. call_args) else output:write('args') end @@ -465,7 +561,7 @@ for i = 1, #functions do end if fn.arena_return then - output:write(', arena') + output:write(', arena') end if fn.has_lua_imp then @@ -492,36 +588,45 @@ for i = 1, #functions do end if fn.return_type ~= 'void' then - output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);') + output:write('\n ret = ' .. string.upper(real_type(fn.return_type)) .. '_OBJ(rv);') end - output:write('\n\ncleanup:'); + output:write('\n\ncleanup:') - output:write('\n return ret;\n}\n\n'); + output:write('\n return ret;\n}\n\n') end end local remote_fns = {} -for _,fn in ipairs(functions) do +for _, fn in ipairs(functions) do if fn.remote then remote_fns[fn.name] = fn end end -remote_fns.redraw = {impl_name="ui_client_redraw", fast=true} +remote_fns.redraw = { impl_name = 'ui_client_redraw', fast = true } local names = vim.tbl_keys(remote_fns) table.sort(names) -local hashorder, hashfun = hashy.hashy_hash("msgpack_rpc_get_handler_for", names, function (idx) - return "method_handlers["..idx.."].name" +local hashorder, hashfun = hashy.hashy_hash('msgpack_rpc_get_handler_for', names, function(idx) + return 'method_handlers[' .. idx .. '].name' end) -output:write("const MsgpackRpcRequestHandler method_handlers[] = {\n") +output:write('const MsgpackRpcRequestHandler method_handlers[] = {\n') for n, name in ipairs(hashorder) do local fn = remote_fns[name] - fn.handler_id = n-1 - output:write(' { .name = "'..name..'", .fn = handle_'.. (fn.impl_name or fn.name).. - ', .fast = '..tostring(fn.fast)..', .arena_return = '..tostring(not not fn.arena_return)..'},\n') + fn.handler_id = n - 1 + output:write( + ' { .name = "' + .. name + .. '", .fn = handle_' + .. (fn.impl_name or fn.name) + .. ', .fast = ' + .. tostring(fn.fast) + .. ', .arena_return = ' + .. tostring(not not fn.arena_return) + .. '},\n' + ) end -output:write("};\n\n") +output:write('};\n\n') output:write(hashfun) output:close() @@ -534,7 +639,7 @@ mpack_output:close() local function include_headers(output_handle, headers_to_include) for i = 1, #headers_to_include do if headers_to_include[i]:sub(-12) ~= '.generated.h' then - output_handle:write('\n#include "nvim/'..headers_to_include[i]..'"') + output_handle:write('\n#include "nvim/' .. headers_to_include[i] .. '"') end end end @@ -572,7 +677,10 @@ local lua_c_functions = {} local function process_function(fn) local lua_c_function_name = ('nlua_api_%s'):format(fn.name) - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ static int %s(lua_State *lstate) { @@ -582,71 +690,108 @@ local function process_function(fn) api_set_error(&err, kErrorTypeValidation, "Expected %i argument%s"); goto exit_0; } - ]], lua_c_function_name, #fn.parameters, #fn.parameters, - (#fn.parameters == 1) and '' or 's')) + ]], + lua_c_function_name, + #fn.parameters, + #fn.parameters, + (#fn.parameters == 1) and '' or 's' + ) + ) lua_c_functions[#lua_c_functions + 1] = { - binding=lua_c_function_name, - api=fn.name + binding = lua_c_function_name, + api = fn.name, } if not fn.fast then - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ if (!nlua_is_deferred_safe()) { return luaL_error(lstate, e_luv_api_disabled, "%s"); } - ]], fn.name)) + ]], + fn.name + ) + ) end if fn.textlock then - write_shifted_output(output, [[ + write_shifted_output( + output, + [[ if (text_locked()) { api_set_error(&err, kErrorTypeException, "%s", get_text_locked_msg()); goto exit_0; } - ]]) + ]] + ) elseif fn.textlock_allow_cmdwin then - write_shifted_output(output, [[ + write_shifted_output( + output, + [[ if (textlock != 0 || expr_map_locked()) { api_set_error(&err, kErrorTypeException, "%s", e_textlock); goto exit_0; } - ]]) + ]] + ) end local cparams = '' local free_code = {} - for j = #fn.parameters,1,-1 do + for j = #fn.parameters, 1, -1 do local param = fn.parameters[j] local cparam = string.format('arg%u', j) local param_type = real_type(param[1]) local lc_param_type = real_type(param[1]):lower() - local extra = param_type == "Dictionary" and "false, " or "" - if param[1] == "Object" or param[1] == "DictionaryOf(LuaRef)" then - extra = "true, " + local extra = param_type == 'Dictionary' and 'false, ' or '' + if param[1] == 'Object' or param[1] == 'DictionaryOf(LuaRef)' then + extra = 'true, ' end local errshift = 0 local seterr = '' if string.match(param_type, '^KeyDict_') then - write_shifted_output(output, string.format([[ - %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, &err_param, &err);]], param_type, cparam, cparam, param_type)) - cparam = '&'..cparam + write_shifted_output( + output, + string.format( + [[ + %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, &err_param, &err);]], + param_type, + cparam, + cparam, + param_type + ) + ) + cparam = '&' .. cparam errshift = 1 -- free incomplete dict on error else - write_shifted_output(output, string.format([[ - const %s %s = nlua_pop_%s(lstate, %s&err);]], param[1], cparam, param_type, extra)) + write_shifted_output( + output, + string.format( + [[ + const %s %s = nlua_pop_%s(lstate, %s&err);]], + param[1], + cparam, + param_type, + extra + ) + ) seterr = [[ - err_param = "]]..param[2]..[[";]] + err_param = "]] .. param[2] .. [[";]] end - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format([[ - if (ERROR_SET(&err)) {]]..seterr..[[ + if (ERROR_SET(&err)) {]] .. seterr .. [[ goto exit_%u; } - ]], #fn.parameters - j + errshift)) - free_code[#free_code + 1] = ('api_free_%s(%s);'):format( - lc_param_type, cparam) + ]], #fn.parameters - j + errshift) + ) + free_code[#free_code + 1] = ('api_free_%s(%s);'):format(lc_param_type, cparam) cparams = cparam .. ', ' .. cparams end if fn.receives_channel_id then @@ -654,9 +799,12 @@ local function process_function(fn) end if fn.arena_return then cparams = cparams .. '&arena, ' - write_shifted_output(output, [[ + write_shifted_output( + output, + [[ Arena arena = ARENA_EMPTY; - ]]) + ]] + ) end if fn.has_lua_imp then @@ -675,8 +823,7 @@ local function process_function(fn) if i == 1 and not string.match(real_type(fn.parameters[1][1]), '^KeyDict_') then free_at_exit_code = free_at_exit_code .. ('\n %s'):format(code) else - free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format( - rev_i, code) + free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format(rev_i, code) end end local err_throw_code = [[ @@ -704,45 +851,86 @@ local function process_function(fn) end local free_retval if fn.arena_return then - free_retval = "arena_mem_free(arena_finish(&arena));" + free_retval = 'arena_mem_free(arena_finish(&arena));' else - free_retval = "api_free_"..return_type:lower().."(ret);" + free_retval = 'api_free_' .. return_type:lower() .. '(ret);' end - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ const %s ret = %s(%s); - ]], fn.return_type, fn.name, cparams)) + ]], + fn.return_type, + fn.name, + cparams + ) + ) if fn.has_lua_imp then -- only push onto the Lua stack if we haven't already - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ if (lua_gettop(lstate) == 0) { nlua_push_%s(lstate, ret, true); } - ]], return_type)) + ]], + return_type + ) + ) else local special = (fn.since ~= nil and fn.since < 11) - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ nlua_push_%s(lstate, ret, %s); - ]], return_type, tostring(special))) + ]], + return_type, + tostring(special) + ) + ) end - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ %s %s %s return 1; - ]], free_retval, free_at_exit_code, err_throw_code)) + ]], + free_retval, + free_at_exit_code, + err_throw_code + ) + ) else - write_shifted_output(output, string.format([[ + write_shifted_output( + output, + string.format( + [[ %s(%s); %s %s return 0; - ]], fn.name, cparams, free_at_exit_code, err_throw_code)) + ]], + fn.name, + cparams, + free_at_exit_code, + err_throw_code + ) + ) end - write_shifted_output(output, [[ + write_shifted_output( + output, + [[ } - ]]) + ]] + ) end for _, fn in ipairs(functions) do @@ -751,18 +939,25 @@ for _, fn in ipairs(functions) do end end -output:write(string.format([[ +output:write(string.format( + [[ void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL; void nlua_add_api_functions(lua_State *lstate) { lua_createtable(lstate, 0, %u); -]], #lua_c_functions)) +]], + #lua_c_functions +)) for _, func in ipairs(lua_c_functions) do - output:write(string.format([[ + output:write(string.format( + [[ lua_pushcfunction(lstate, &%s); - lua_setfield(lstate, -2, "%s");]], func.binding, func.api)) + lua_setfield(lstate, -2, "%s");]], + func.binding, + func.api + )) end output:write([[ diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua index e2af5f8d44..89f8c654f4 100644 --- a/src/nvim/generators/gen_api_ui_events.lua +++ b/src/nvim/generators/gen_api_ui_events.lua @@ -10,11 +10,11 @@ local client_output = io.open(arg[5], 'wb') local c_grammar = require('generators.c_grammar') local events = c_grammar.grammar:match(input:read('*all')) -local hashy = require'generators.hashy' +local hashy = require 'generators.hashy' local function write_signature(output, ev, prefix, notype) - output:write('('..prefix) - if prefix == "" and #ev.parameters == 0 then + output:write('(' .. prefix) + if prefix == '' and #ev.parameters == 0 then output:write('void') end for j = 1, #ev.parameters do @@ -23,7 +23,7 @@ local function write_signature(output, ev, prefix, notype) end local param = ev.parameters[j] if not notype then - output:write(param[1]..' ') + output:write(param[1] .. ' ') end output:write(param[2]) end @@ -35,26 +35,28 @@ local function write_arglist(output, ev) local param = ev.parameters[j] local kind = string.upper(param[1]) output:write(' ADD_C(args, ') - output:write(kind..'_OBJ('..param[2]..')') + output:write(kind .. '_OBJ(' .. param[2] .. ')') output:write(');\n') end end local function call_ui_event_method(output, ev) - output:write('void ui_client_event_'..ev.name..'(Array args)\n{\n') + output:write('void ui_client_event_' .. ev.name .. '(Array args)\n{\n') local hlattrs_args_count = 0 if #ev.parameters > 0 then - output:write(' if (args.size < '..(#ev.parameters)) + output:write(' if (args.size < ' .. #ev.parameters) for j = 1, #ev.parameters do local kind = ev.parameters[j][1] - if kind ~= "Object" then - if kind == 'HlAttrs' then kind = 'Dictionary' end - output:write('\n || args.items['..(j-1)..'].type != kObjectType'..kind..'') + if kind ~= 'Object' then + if kind == 'HlAttrs' then + kind = 'Dictionary' + end + output:write('\n || args.items[' .. (j - 1) .. '].type != kObjectType' .. kind .. '') end end output:write(') {\n') - output:write(' ELOG("Error handling ui event \''..ev.name..'\'");\n') + output:write(' ELOG("Error handling ui event \'' .. ev.name .. '\'");\n') output:write(' return;\n') output:write(' }\n') end @@ -62,23 +64,29 @@ local function call_ui_event_method(output, ev) for j = 1, #ev.parameters do local param = ev.parameters[j] local kind = param[1] - output:write(' '..kind..' arg_'..j..' = ') + output:write(' ' .. kind .. ' arg_' .. j .. ' = ') if kind == 'HlAttrs' then -- The first HlAttrs argument is rgb_attrs and second is cterm_attrs - output:write('ui_client_dict2hlattrs(args.items['..(j-1)..'].data.dictionary, '..(hlattrs_args_count == 0 and 'true' or 'false')..');\n') + output:write( + 'ui_client_dict2hlattrs(args.items[' + .. (j - 1) + .. '].data.dictionary, ' + .. (hlattrs_args_count == 0 and 'true' or 'false') + .. ');\n' + ) hlattrs_args_count = hlattrs_args_count + 1 elseif kind == 'Object' then - output:write('args.items['..(j-1)..'];\n') + output:write('args.items[' .. (j - 1) .. '];\n') elseif kind == 'Window' then - output:write('(Window)args.items['..(j-1)..'].data.integer;\n') + output:write('(Window)args.items[' .. (j - 1) .. '].data.integer;\n') else - output:write('args.items['..(j-1)..'].data.'..string.lower(kind)..';\n') + output:write('args.items[' .. (j - 1) .. '].data.' .. string.lower(kind) .. ';\n') end end - output:write(' tui_'..ev.name..'(tui') + output:write(' tui_' .. ev.name .. '(tui') for j = 1, #ev.parameters do - output:write(', arg_'..j) + output:write(', arg_' .. j) end output:write(');\n') @@ -90,78 +98,81 @@ for i = 1, #events do assert(ev.return_type == 'void') if ev.since == nil and not ev.noexport then - print("Ui event "..ev.name.." lacks since field.\n") + print('Ui event ' .. ev.name .. ' lacks since field.\n') os.exit(1) end ev.since = tonumber(ev.since) if not ev.remote_only then - if not ev.remote_impl and not ev.noexport then - remote_output:write('void remote_ui_'..ev.name) + remote_output:write('void remote_ui_' .. ev.name) write_signature(remote_output, ev, 'UI *ui') remote_output:write('\n{\n') remote_output:write(' UIData *data = ui->data;\n') remote_output:write(' Array args = data->call_buf;\n') write_arglist(remote_output, ev) - remote_output:write(' push_call(ui, "'..ev.name..'", args);\n') + remote_output:write(' push_call(ui, "' .. ev.name .. '", args);\n') remote_output:write('}\n\n') end end if not (ev.remote_only and ev.remote_impl) then - call_output:write('void ui_call_'..ev.name) + call_output:write('void ui_call_' .. ev.name) write_signature(call_output, ev, '') call_output:write('\n{\n') if ev.remote_only then call_output:write(' Array args = call_buf;\n') write_arglist(call_output, ev) - call_output:write(' ui_call_event("'..ev.name..'", args);\n') + call_output:write(' ui_call_event("' .. ev.name .. '", args);\n') elseif ev.compositor_impl then - call_output:write(' ui_comp_'..ev.name) + call_output:write(' ui_comp_' .. ev.name) write_signature(call_output, ev, '', true) - call_output:write(";\n") + call_output:write(';\n') call_output:write(' UI_CALL') - write_signature(call_output, ev, '!ui->composed, '..ev.name..', ui', true) - call_output:write(";\n") + write_signature(call_output, ev, '!ui->composed, ' .. ev.name .. ', ui', true) + call_output:write(';\n') else call_output:write(' UI_CALL') - write_signature(call_output, ev, 'true, '..ev.name..', ui', true) - call_output:write(";\n") + write_signature(call_output, ev, 'true, ' .. ev.name .. ', ui', true) + call_output:write(';\n') end - call_output:write("}\n\n") + call_output:write('}\n\n') end if ev.compositor_impl then - call_output:write('void ui_composed_call_'..ev.name) + call_output:write('void ui_composed_call_' .. ev.name) write_signature(call_output, ev, '') call_output:write('\n{\n') call_output:write(' UI_CALL') - write_signature(call_output, ev, 'ui->composed, '..ev.name..', ui', true) - call_output:write(";\n") - call_output:write("}\n\n") + write_signature(call_output, ev, 'ui->composed, ' .. ev.name .. ', ui', true) + call_output:write(';\n') + call_output:write('}\n\n') end - if (not ev.remote_only) and (not ev.noexport) and (not ev.client_impl) and (not ev.client_ignore) then + if (not ev.remote_only) and not ev.noexport and not ev.client_impl and not ev.client_ignore then call_ui_event_method(client_output, ev) end end local client_events = {} -for _,ev in ipairs(events) do - if (not ev.noexport) and ((not ev.remote_only) or ev.client_impl) and (not ev.client_ignore) then +for _, ev in ipairs(events) do + if (not ev.noexport) and ((not ev.remote_only) or ev.client_impl) and not ev.client_ignore then client_events[ev.name] = ev end end -local hashorder, hashfun = hashy.hashy_hash("ui_client_handler", vim.tbl_keys(client_events), function (idx) - return "event_handlers["..idx.."].name" -end) +local hashorder, hashfun = hashy.hashy_hash( + 'ui_client_handler', + vim.tbl_keys(client_events), + function(idx) + return 'event_handlers[' .. idx .. '].name' + end +) -client_output:write("static const UIClientHandler event_handlers[] = {\n") +client_output:write('static const UIClientHandler event_handlers[] = {\n') for _, name in ipairs(hashorder) do - client_output:write(' { .name = "'..name..'", .fn = ui_client_event_'..name..'},\n') + client_output:write(' { .name = "' .. name .. '", .fn = ui_client_event_' .. name .. '},\n') end client_output:write('\n};\n\n') @@ -172,25 +183,24 @@ remote_output:close() client_output:close() -- don't expose internal attributes like "impl_name" in public metadata -local exported_attributes = {'name', 'parameters', - 'since', 'deprecated_since'} +local exported_attributes = { 'name', 'parameters', 'since', 'deprecated_since' } local exported_events = {} -for _,ev in ipairs(events) do +for _, ev in ipairs(events) do local ev_exported = {} - for _,attr in ipairs(exported_attributes) do + for _, attr in ipairs(exported_attributes) do ev_exported[attr] = ev[attr] end - for _,p in ipairs(ev_exported.parameters) do + for _, p in ipairs(ev_exported.parameters) do if p[1] == 'HlAttrs' then p[1] = 'Dictionary' end end if not ev.noexport then - exported_events[#exported_events+1] = ev_exported + exported_events[#exported_events + 1] = ev_exported end end local packed = mpack.encode(exported_events) -local dump_bin_array = require("generators.dump_bin_array") +local dump_bin_array = require('generators.dump_bin_array') dump_bin_array(metadata_output, 'ui_events_metadata', packed) metadata_output:close() diff --git a/src/nvim/generators/gen_char_blob.lua b/src/nvim/generators/gen_char_blob.lua index 11f6cbcc13..c40e0d6e82 100644 --- a/src/nvim/generators/gen_char_blob.lua +++ b/src/nvim/generators/gen_char_blob.lua @@ -1,6 +1,6 @@ if arg[1] == '--help' then print('Usage:') - print(' '..arg[0]..' [-c] target source varname [source varname]...') + print(' ' .. arg[0] .. ' [-c] target source varname [source varname]...') print('') print('Generates C file with big uint8_t blob.') print('Blob will be stored in a static const array named varname.') @@ -12,7 +12,7 @@ end local options = {} while true do - local opt = string.match(arg[1], "^-(%w)") + local opt = string.match(arg[1], '^-(%w)') if not opt then break end @@ -36,33 +36,33 @@ for argi = 2, #arg, 2 do local source_file = arg[argi] local modname = arg[argi + 1] if modnames[modname] then - error(string.format("modname %q is already specified for file %q", modname, modnames[modname])) + error(string.format('modname %q is already specified for file %q', modname, modnames[modname])) end modnames[modname] = source_file - local varname = string.gsub(modname,'%.','_dot_').."_module" + local varname = string.gsub(modname, '%.', '_dot_') .. '_module' target:write(('static const uint8_t %s[] = {\n'):format(varname)) local output if options.c then - local luac = os.getenv("LUAC_PRG") - if luac and luac ~= "" then - output = io.popen(luac:format(source_file), "r"):read("*a") + local luac = os.getenv('LUAC_PRG') + if luac and luac ~= '' then + output = io.popen(luac:format(source_file), 'r'):read('*a') elseif warn_on_missing_compiler then - print("LUAC_PRG is missing, embedding raw source") + print('LUAC_PRG is missing, embedding raw source') warn_on_missing_compiler = false end end if not output then - local source = io.open(source_file, "r") - or error(string.format("source_file %q doesn't exist", source_file)) - output = source:read("*a") + local source = io.open(source_file, 'r') + or error(string.format("source_file %q doesn't exist", source_file)) + output = source:read('*a') source:close() end local num_bytes = 0 - local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line + local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line target:write(' ') local increase_num_bytes @@ -81,8 +81,11 @@ for argi = 2, #arg, 2 do end target:write(' 0};\n') - if modname ~= "_" then - table.insert(index_items, ' { "'..modname..'", '..varname..', sizeof '..varname..' },\n\n') + if modname ~= '_' then + table.insert( + index_items, + ' { "' .. modname .. '", ' .. varname .. ', sizeof ' .. varname .. ' },\n\n' + ) end end diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua index fecca5191e..9fd2750f52 100644 --- a/src/nvim/generators/gen_declarations.lua +++ b/src/nvim/generators/gen_declarations.lua @@ -5,9 +5,9 @@ local preproc_fname = arg[4] local lpeg = vim.lpeg -local fold = function (func, ...) +local fold = function(func, ...) local result = nil - for _, v in ipairs({...}) do + for _, v in ipairs({ ... }) do if result == nil then result = v else @@ -17,144 +17,112 @@ local fold = function (func, ...) return result end -local folder = function (func) - return function (...) +local folder = function(func) + return function(...) return fold(func, ...) end end local lit = lpeg.P local set = function(...) - return lpeg.S(fold(function (a, b) return a .. b end, ...)) + return lpeg.S(fold(function(a, b) + return a .. b + end, ...)) end local any_character = lpeg.P(1) -local rng = function(s, e) return lpeg.R(s .. e) end -local concat = folder(function (a, b) return a * b end) -local branch = folder(function (a, b) return a + b end) -local one_or_more = function(v) return v ^ 1 end -local two_or_more = function(v) return v ^ 2 end -local any_amount = function(v) return v ^ 0 end -local one_or_no = function(v) return v ^ -1 end +local rng = function(s, e) + return lpeg.R(s .. e) +end +local concat = folder(function(a, b) + return a * b +end) +local branch = folder(function(a, b) + return a + b +end) +local one_or_more = function(v) + return v ^ 1 +end +local two_or_more = function(v) + return v ^ 2 +end +local any_amount = function(v) + return v ^ 0 +end +local one_or_no = function(v) + return v ^ -1 +end local look_behind = lpeg.B -local look_ahead = function(v) return #v end -local neg_look_ahead = function(v) return -v end -local neg_look_behind = function(v) return -look_behind(v) end +local look_ahead = function(v) + return #v +end +local neg_look_ahead = function(v) + return -v +end +local neg_look_behind = function(v) + return -look_behind(v) +end -local w = branch( - rng('a', 'z'), - rng('A', 'Z'), - lit('_') -) -local aw = branch( - w, - rng('0', '9') -) +local w = branch(rng('a', 'z'), rng('A', 'Z'), lit('_')) +local aw = branch(w, rng('0', '9')) local s = set(' ', '\n', '\t') local raw_word = concat(w, any_amount(aw)) -local right_word = concat( - raw_word, - neg_look_ahead(aw) -) +local right_word = concat(raw_word, neg_look_ahead(aw)) local word = branch( concat( branch(lit('ArrayOf('), lit('DictionaryOf('), lit('Dict(')), -- typed container macro one_or_more(any_character - lit(')')), lit(')') ), - concat( - neg_look_behind(aw), - right_word - ) -) -local inline_comment = concat( - lit('/*'), - any_amount(concat( - neg_look_ahead(lit('*/')), - any_character - )), - lit('*/') + concat(neg_look_behind(aw), right_word) ) +local inline_comment = + concat(lit('/*'), any_amount(concat(neg_look_ahead(lit('*/')), any_character)), lit('*/')) local spaces = any_amount(branch( s, -- Comments are really handled by preprocessor, so the following is not needed inline_comment, - concat( - lit('//'), - any_amount(concat( - neg_look_ahead(lit('\n')), - any_character - )), - lit('\n') - ), + concat(lit('//'), any_amount(concat(neg_look_ahead(lit('\n')), any_character)), lit('\n')), -- Linemarker inserted by preprocessor - concat( - lit('# '), - any_amount(concat( - neg_look_ahead(lit('\n')), - any_character - )), - lit('\n') - ) + concat(lit('# '), any_amount(concat(neg_look_ahead(lit('\n')), any_character)), lit('\n')) )) -local typ_part = concat( - word, - any_amount(concat( - spaces, - lit('*') - )), - spaces -) +local typ_part = concat(word, any_amount(concat(spaces, lit('*'))), spaces) local typ_id = two_or_more(typ_part) -local arg = typ_id -- argument name is swallowed by typ +local arg = typ_id -- argument name is swallowed by typ local pattern = concat( any_amount(branch(set(' ', '\t'), inline_comment)), - typ_id, -- return type with function name + typ_id, -- return type with function name spaces, lit('('), spaces, - one_or_no(branch( -- function arguments + one_or_no(branch( -- function arguments concat( - arg, -- first argument, does not require comma - any_amount(concat( -- following arguments, start with a comma + arg, -- first argument, does not require comma + any_amount(concat( -- following arguments, start with a comma spaces, lit(','), spaces, arg, - any_amount(concat( - lit('['), - spaces, - any_amount(aw), - spaces, - lit(']') - )) + any_amount(concat(lit('['), spaces, any_amount(aw), spaces, lit(']'))) )), - one_or_no(concat( - spaces, - lit(','), - spaces, - lit('...') - )) + one_or_no(concat(spaces, lit(','), spaces, lit('...'))) ), - lit('void') -- also accepts just void + lit('void') -- also accepts just void )), spaces, lit(')'), - any_amount(concat( -- optional attributes + any_amount(concat( -- optional attributes spaces, lit('FUNC_'), any_amount(aw), - one_or_no(concat( -- attribute argument + one_or_no(concat( -- attribute argument spaces, lit('('), - any_amount(concat( - neg_look_ahead(lit(')')), - any_character - )), + any_amount(concat(neg_look_ahead(lit(')')), any_character)), lit(')') )) )), - look_ahead(concat( -- definition must be followed by "{" + look_ahead(concat( -- definition must be followed by "{" spaces, lit('{') )) @@ -198,10 +166,9 @@ Additionally uses the following environment variables: end local preproc_f = io.open(preproc_fname) -local text = preproc_f:read("*all") +local text = preproc_f:read('*all') preproc_f:close() - local non_static = [[ #define DEFINE_FUNC_ATTRIBUTES #include "nvim/func_attr.h" @@ -289,8 +256,7 @@ while init ~= nil do declaration = declaration .. ';' if os.getenv('NVIM_GEN_DECLARATIONS_LINE_NUMBERS') == '1' then - declaration = declaration .. (' // %s/%s:%u'):format( - curdir, curfile, declline) + declaration = declaration .. (' // %s/%s:%u'):format(curdir, curfile, declline) end declaration = declaration .. '\n' if declaration:sub(1, 6) == 'static' then diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua index 7b272c337e..1ce7f1af9d 100644 --- a/src/nvim/generators/gen_eval.lua +++ b/src/nvim/generators/gen_eval.lua @@ -8,7 +8,7 @@ local funcsfname = autodir .. '/funcs.generated.h' --Will generate funcs.generated.h with definition of functions static const array. -local hashy = require'generators.hashy' +local hashy = require 'generators.hashy' local hashpipe = assert(io.open(funcsfname, 'wb')) @@ -48,18 +48,18 @@ hashpipe:write([[ local funcs = require('eval').funcs for _, func in pairs(funcs) do if func.float_func then - func.func = "float_op_wrapper" - func.data = "{ .float_func = &"..func.float_func.." }" + func.func = 'float_op_wrapper' + func.data = '{ .float_func = &' .. func.float_func .. ' }' end end -local metadata = mpack.decode(io.open(metadata_file, 'rb'):read("*all")) -for _,fun in ipairs(metadata) do +local metadata = mpack.decode(io.open(metadata_file, 'rb'):read('*all')) +for _, fun in ipairs(metadata) do if fun.eval then funcs[fun.name] = { - args=#fun.parameters, - func='api_wrapper', - data='{ .api_handler = &method_handlers['..fun.handler_id..'] }' + args = #fun.parameters, + func = 'api_wrapper', + data = '{ .api_handler = &method_handlers[' .. fun.handler_id .. '] }', } end end @@ -74,28 +74,37 @@ local funcsdata = assert(io.open(funcs_file, 'w')) funcsdata:write(mpack.encode(func_names)) funcsdata:close() -local neworder, hashfun = hashy.hashy_hash("find_internal_func", func_names, function (idx) - return "functions["..idx.."].name" +local neworder, hashfun = hashy.hashy_hash('find_internal_func', func_names, function(idx) + return 'functions[' .. idx .. '].name' end) -hashpipe:write("static const EvalFuncDef functions[] = {\n") +hashpipe:write('static const EvalFuncDef functions[] = {\n') for _, name in ipairs(neworder) do local def = funcs[name] local args = def.args or 0 if type(args) == 'number' then - args = {args, args} + args = { args, args } elseif #args == 1 then args[2] = 'MAX_FUNC_ARGS' end - local base = def.base or "BASE_NONE" + local base = def.base or 'BASE_NONE' local func = def.func or ('f_' .. name) - local data = def.data or "{ .null = NULL }" + local data = def.data or '{ .null = NULL }' local fast = def.fast and 'true' or 'false' - hashpipe:write((' { "%s", %s, %s, %s, %s, &%s, %s },\n') - :format(name, args[1], args[2], base, fast, func, data)) + hashpipe:write( + (' { "%s", %s, %s, %s, %s, &%s, %s },\n'):format( + name, + args[1], + args[2], + base, + fast, + func, + data + ) + ) end hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, { .null = NULL } },\n') -hashpipe:write("};\n\n") +hashpipe:write('};\n\n') hashpipe:write(hashfun) hashpipe:close() diff --git a/src/nvim/generators/gen_events.lua b/src/nvim/generators/gen_events.lua index 4763a2f463..ee48e918e8 100644 --- a/src/nvim/generators/gen_events.lua +++ b/src/nvim/generators/gen_events.lua @@ -22,7 +22,7 @@ static const struct event_name { for i, event in ipairs(events) do enum_tgt:write(('\n EVENT_%s = %u,'):format(event:upper(), i - 1)) names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#event, event, event:upper())) - if i == #events then -- Last item. + if i == #events then -- Last item. enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i)) end end @@ -41,15 +41,15 @@ names_tgt:write('\n};\n') do names_tgt:write('\nstatic AutoCmdVec autocmds[NUM_EVENTS] = {\n ') local line_len = 1 - for _ = 1,((#events) - 1) do - line_len = line_len + #(' KV_INITIAL_VALUE,') + for _ = 1, (#events - 1) do + line_len = line_len + #' KV_INITIAL_VALUE,' if line_len > 80 then names_tgt:write('\n ') - line_len = 1 + #(' KV_INITIAL_VALUE,') + line_len = 1 + #' KV_INITIAL_VALUE,' end names_tgt:write(' KV_INITIAL_VALUE,') end - if line_len + #(' KV_INITIAL_VALUE') > 80 then + if line_len + #' KV_INITIAL_VALUE' > 80 then names_tgt:write('\n KV_INITIAL_VALUE') else names_tgt:write(' KV_INITIAL_VALUE') diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua index ae8c952648..e8d1aac182 100644 --- a/src/nvim/generators/gen_ex_cmds.lua +++ b/src/nvim/generators/gen_ex_cmds.lua @@ -21,24 +21,32 @@ local a_to_z = byte_z - byte_a + 1 -- Table giving the index of the first command in cmdnames[] to lookup -- based on the first letter of a command. -local cmdidxs1_out = string.format([[ +local cmdidxs1_out = string.format( + [[ static const uint16_t cmdidxs1[%u] = { -]], a_to_z) +]], + a_to_z +) -- Table giving the index of the first command in cmdnames[] to lookup -- based on the first 2 letters of a command. -- Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they -- fit in a byte. -local cmdidxs2_out = string.format([[ +local cmdidxs2_out = string.format( + [[ static const uint8_t cmdidxs2[%u][%u] = { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ -]], a_to_z, a_to_z) +]], + a_to_z, + a_to_z +) enumfile:write([[ // IWYU pragma: private, include "nvim/ex_cmds_defs.h" typedef enum CMD_index { ]]) -defsfile:write(string.format([[ +defsfile:write(string.format( + [[ #include "nvim/arglist.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" @@ -79,23 +87,34 @@ defsfile:write(string.format([[ static const int command_count = %u; static CommandDefinition cmdnames[%u] = { -]], #defs, #defs)) +]], + #defs, + #defs +)) local cmds, cmdidxs1, cmdidxs2 = {}, {}, {} for _, cmd in ipairs(defs) do if bit.band(cmd.flags, flags.RANGE) == flags.RANGE then - assert(cmd.addr_type ~= 'ADDR_NONE', - string.format('ex_cmds.lua:%s: Using RANGE with ADDR_NONE\n', cmd.command)) + assert( + cmd.addr_type ~= 'ADDR_NONE', + string.format('ex_cmds.lua:%s: Using RANGE with ADDR_NONE\n', cmd.command) + ) else - assert(cmd.addr_type == 'ADDR_NONE', - string.format('ex_cmds.lua:%s: Missing ADDR_NONE\n', cmd.command)) + assert( + cmd.addr_type == 'ADDR_NONE', + string.format('ex_cmds.lua:%s: Missing ADDR_NONE\n', cmd.command) + ) end if bit.band(cmd.flags, flags.DFLALL) == flags.DFLALL then - assert(cmd.addr_type ~= 'ADDR_OTHER' and cmd.addr_type ~= 'ADDR_NONE', - string.format('ex_cmds.lua:%s: Missing misplaced DFLALL\n', cmd.command)) + assert( + cmd.addr_type ~= 'ADDR_OTHER' and cmd.addr_type ~= 'ADDR_NONE', + string.format('ex_cmds.lua:%s: Missing misplaced DFLALL\n', cmd.command) + ) end if bit.band(cmd.flags, flags.PREVIEW) == flags.PREVIEW then - assert(cmd.preview_func ~= nil, - string.format('ex_cmds.lua:%s: Missing preview_func\n', cmd.command)) + assert( + cmd.preview_func ~= nil, + string.format('ex_cmds.lua:%s: Missing preview_func\n', cmd.command) + ) end local enumname = cmd.enum or ('CMD_' .. cmd.command) local byte_cmd = cmd.command:sub(1, 1):byte() @@ -104,12 +123,13 @@ for _, cmd in ipairs(defs) do end local preview_func if cmd.preview_func then - preview_func = string.format("&%s", cmd.preview_func) + preview_func = string.format('&%s', cmd.preview_func) else - preview_func = "NULL" + preview_func = 'NULL' end enumfile:write(' ' .. enumname .. ',\n') - defsfile:write(string.format([[ + defsfile:write(string.format( + [[ [%s] = { .cmd_name = "%s", .cmd_func = (ex_func_T)&%s, @@ -117,7 +137,14 @@ for _, cmd in ipairs(defs) do .cmd_argt = %uL, .cmd_addr_type = %s }, -]], enumname, cmd.command, cmd.func, preview_func, cmd.flags, cmd.addr_type)) +]], + enumname, + cmd.command, + cmd.func, + preview_func, + cmd.flags, + cmd.addr_type + )) end for i = #cmds, 1, -1 do local cmd = cmds[i] @@ -141,10 +168,12 @@ for i = byte_a, byte_z do cmdidxs2_out = cmdidxs2_out .. ' /* ' .. c1 .. ' */ {' for j = byte_a, byte_z do local c2 = string.char(j) - cmdidxs2_out = cmdidxs2_out .. - ((cmdidxs2[c1] and cmdidxs2[c1][c2]) - and string.format('%3d', cmdidxs2[c1][c2] - cmdidxs1[c1]) - or ' 0') .. ',' + cmdidxs2_out = cmdidxs2_out + .. ((cmdidxs2[c1] and cmdidxs2[c1][c2]) and string.format( + '%3d', + cmdidxs2[c1][c2] - cmdidxs1[c1] + ) or ' 0') + .. ',' end cmdidxs2_out = cmdidxs2_out .. ' },\n' end @@ -154,8 +183,12 @@ enumfile:write([[ CMD_USER_BUF = -2 } cmdidx_T; ]]) -defsfile:write(string.format([[ +defsfile:write(string.format( + [[ }; %s}; %s}; -]], cmdidxs1_out, cmdidxs2_out)) +]], + cmdidxs1_out, + cmdidxs2_out +)) diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 26ade2745d..3a355634f3 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -15,37 +15,37 @@ local options = require('options') local cstr = options.cstr -local type_flags={ - bool='P_BOOL', - number='P_NUM', - string='P_STRING', +local type_flags = { + bool = 'P_BOOL', + number = 'P_NUM', + string = 'P_STRING', } -local redraw_flags={ - ui_option='P_UI_OPTION', - tabline='P_RTABL', - statuslines='P_RSTAT', - current_window='P_RWIN', - current_window_only='P_RWINONLY', - current_buffer='P_RBUF', - all_windows='P_RALL', - curswant='P_CURSWANT', +local redraw_flags = { + ui_option = 'P_UI_OPTION', + tabline = 'P_RTABL', + statuslines = 'P_RSTAT', + current_window = 'P_RWIN', + current_window_only = 'P_RWINONLY', + current_buffer = 'P_RBUF', + all_windows = 'P_RALL', + curswant = 'P_CURSWANT', } -local list_flags={ - comma='P_COMMA', - onecomma='P_ONECOMMA', - commacolon='P_COMMA|P_COLON', - onecommacolon='P_ONECOMMA|P_COLON', - flags='P_FLAGLIST', - flagscomma='P_COMMA|P_FLAGLIST', +local list_flags = { + comma = 'P_COMMA', + onecomma = 'P_ONECOMMA', + commacolon = 'P_COMMA|P_COLON', + onecommacolon = 'P_ONECOMMA|P_COLON', + flags = 'P_FLAGLIST', + flagscomma = 'P_COMMA|P_FLAGLIST', } --- @param o vim.option_meta --- @return string local function get_flags(o) --- @type string[] - local ret = {type_flags[o.type]} + local ret = { type_flags[o.type] } local add_flag = function(f) ret[1] = ret[1] .. '|' .. f end @@ -64,19 +64,19 @@ local function get_flags(o) end end for _, flag_desc in ipairs({ - {'alloced'}, - {'nodefault'}, - {'no_mkrc'}, - {'secure'}, - {'gettext'}, - {'noglob'}, - {'normal_fname_chars', 'P_NFNAME'}, - {'normal_dname_chars', 'P_NDNAME'}, - {'pri_mkrc'}, - {'deny_in_modelines', 'P_NO_ML'}, - {'deny_duplicates', 'P_NODUP'}, - {'modelineexpr', 'P_MLE'}, - {'func'} + { 'alloced' }, + { 'nodefault' }, + { 'no_mkrc' }, + { 'secure' }, + { 'gettext' }, + { 'noglob' }, + { 'normal_fname_chars', 'P_NFNAME' }, + { 'normal_dname_chars', 'P_NDNAME' }, + { 'pri_mkrc' }, + { 'deny_in_modelines', 'P_NO_ML' }, + { 'deny_duplicates', 'P_NODUP' }, + { 'modelineexpr', 'P_MLE' }, + { 'func' }, }) do local key_name = flag_desc[1] local def_name = flag_desc[2] or ('P_' .. key_name:upper()) @@ -108,20 +108,28 @@ local function get_cond(c, base_string) end local value_dumpers = { - ['function']=function(v) return v() end, - string=cstr, - boolean=function(v) return v and 'true' or 'false' end, - number=function(v) return ('%iL'):format(v) end, - ['nil']=function(_) return '0' end, + ['function'] = function(v) + return v() + end, + string = cstr, + boolean = function(v) + return v and 'true' or 'false' + end, + number = function(v) + return ('%iL'):format(v) + end, + ['nil'] = function(_) + return '0' + end, } local get_value = function(v) return '(void *) ' .. value_dumpers[type(v)](v) end -local get_defaults = function(d,n) +local get_defaults = function(d, n) if d == nil then - error("option '"..n.."' should have a default value") + error("option '" .. n .. "' should have a default value") end return get_value(d) end @@ -153,20 +161,21 @@ local function dump_option(i, o) if #o.scope == 1 and o.scope[1] == 'global' then w(' .indir=PV_NONE') else - assert (#o.scope == 1 or #o.scope == 2) - assert (#o.scope == 1 or o.scope[1] == 'global') + assert(#o.scope == 1 or #o.scope == 2) + assert(#o.scope == 1 or o.scope[1] == 'global') local min_scope = o.scope[#o.scope] - local varname = o.pv_name or o.varname or ( - 'p_' .. (o.abbreviation or o.full_name)) + local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name)) local pv_name = ( - 'OPT_' .. min_scope:sub(1, 3):upper() .. '(' .. ( - min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper() - ) .. ')' + 'OPT_' + .. min_scope:sub(1, 3):upper() + .. '(' + .. (min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper()) + .. ')' ) if #o.scope == 2 then pv_name = 'OPT_BOTH(' .. pv_name .. ')' end - table.insert(defines, { 'PV_' .. varname:sub(3):upper() , pv_name}) + table.insert(defines, { 'PV_' .. varname:sub(3):upper(), pv_name }) w(' .indir=' .. pv_name) end if o.cb then diff --git a/src/nvim/generators/gen_unicode_tables.lua b/src/nvim/generators/gen_unicode_tables.lua index 9ad99c8029..6cedb5db50 100644 --- a/src/nvim/generators/gen_unicode_tables.lua +++ b/src/nvim/generators/gen_unicode_tables.lua @@ -60,12 +60,10 @@ local fp_lines_to_lists = function(fp, n, has_comments) if not line then break end - if (not has_comments - or (line:sub(1, 1) ~= '#' and not line:match('^%s*$'))) then + if not has_comments or (line:sub(1, 1) ~= '#' and not line:match('^%s*$')) then local l = split_on_semicolons(line) if #l ~= n then - io.stderr:write(('Found %s items in line %u, expected %u\n'):format( - #l, i, n)) + io.stderr:write(('Found %s items in line %u, expected %u\n'):format(#l, i, n)) io.stderr:write('Line: ' .. line .. '\n') return nil end @@ -93,15 +91,13 @@ end local make_range = function(start, end_, step, add) if step and add then - return (' {0x%x, 0x%x, %d, %d},\n'):format( - start, end_, step == 0 and -1 or step, add) + return (' {0x%x, 0x%x, %d, %d},\n'):format(start, end_, step == 0 and -1 or step, add) else return (' {0x%04x, 0x%04x},\n'):format(start, end_) end end -local build_convert_table = function(ut_fp, props, cond_func, nl_index, - table_name) +local build_convert_table = function(ut_fp, props, cond_func, nl_index, table_name) ut_fp:write('static const convertStruct ' .. table_name .. '[] = {\n') local start = -1 local end_ = -1 @@ -137,8 +133,7 @@ local build_case_table = function(ut_fp, dataprops, table_name, index) local cond_func = function(p) return p[index] ~= '' end - return build_convert_table(ut_fp, dataprops, cond_func, index, - 'to' .. table_name) + return build_convert_table(ut_fp, dataprops, cond_func, index, 'to' .. table_name) end local build_fold_table = function(ut_fp, foldprops) @@ -154,7 +149,7 @@ local build_combining_table = function(ut_fp, dataprops) local end_ = -1 for _, p in ipairs(dataprops) do -- The 'Mc' property was removed, it does take up space. - if (({Mn=true, Me=true})[p[3]]) then + if ({ Mn = true, Me = true })[p[3]] then local n = tonumber(p[1], 16) if start >= 0 and end_ + 1 == n then -- Continue with the same range. @@ -175,8 +170,7 @@ local build_combining_table = function(ut_fp, dataprops) ut_fp:write('};\n') end -local build_width_table = function(ut_fp, dataprops, widthprops, widths, - table_name) +local build_width_table = function(ut_fp, dataprops, widthprops, widths, table_name) ut_fp:write('static const struct interval ' .. table_name .. '[] = {\n') local start = -1 local end_ = -1 @@ -208,13 +202,13 @@ local build_width_table = function(ut_fp, dataprops, widthprops, widths, -- Only use the char when it’s not a composing char. -- But use all chars from a range. local dp = dataprops[dataidx] - if (n_last > n) or (not (({Mn=true, Mc=true, Me=true})[dp[3]])) then + if (n_last > n) or not ({ Mn = true, Mc = true, Me = true })[dp[3]] then if start >= 0 and end_ + 1 == n then -- luacheck: ignore 542 -- Continue with the same range. else if start >= 0 then ut_fp:write(make_range(start, end_)) - table.insert(ret, {start, end_}) + table.insert(ret, { start, end_ }) end start = n end @@ -224,7 +218,7 @@ local build_width_table = function(ut_fp, dataprops, widthprops, widths, end if start >= 0 then ut_fp:write(make_range(start, end_)) - table.insert(ret, {start, end_}) + table.insert(ret, { start, end_ }) end ut_fp:write('};\n') return ret @@ -316,10 +310,9 @@ local eaw_fp = io.open(eastasianwidth_fname, 'r') local widthprops = parse_width_props(eaw_fp) eaw_fp:close() -local doublewidth = build_width_table(ut_fp, dataprops, widthprops, - {W=true, F=true}, 'doublewidth') -local ambiwidth = build_width_table(ut_fp, dataprops, widthprops, - {A=true}, 'ambiguous') +local doublewidth = + build_width_table(ut_fp, dataprops, widthprops, { W = true, F = true }, 'doublewidth') +local ambiwidth = build_width_table(ut_fp, dataprops, widthprops, { A = true }, 'ambiguous') local emoji_fp = io.open(emoji_fname, 'r') local emojiprops = parse_emoji_props(emoji_fp) diff --git a/src/nvim/generators/gen_vimvim.lua b/src/nvim/generators/gen_vimvim.lua index 29355d3cda..4d1c82a322 100644 --- a/src/nvim/generators/gen_vimvim.lua +++ b/src/nvim/generators/gen_vimvim.lua @@ -41,12 +41,14 @@ end -- Exclude these from the vimCommand keyword list, they are handled specially -- in syntax/vim.vim (vimAugroupKey, vimAutoCmd, vimGlobal, vimSubst). #9327 local function is_special_cased_cmd(cmd) - return (cmd == 'augroup' - or cmd == 'autocmd' - or cmd == 'doautocmd' - or cmd == 'doautoall' - or cmd == 'global' - or cmd == 'substitute') + return ( + cmd == 'augroup' + or cmd == 'autocmd' + or cmd == 'doautocmd' + or cmd == 'doautoall' + or cmd == 'global' + or cmd == 'substitute' + ) end local vimcmd_start = 'syn keyword vimCommand contained ' @@ -133,7 +135,7 @@ end w('\n\nsyn case match') local vimfun_start = 'syn keyword vimFuncName contained ' w('\n\n' .. vimfun_start) -local funcs = mpack.decode(io.open(funcs_file, 'rb'):read("*all")) +local funcs = mpack.decode(io.open(funcs_file, 'rb'):read('*all')) for _, name in ipairs(funcs) do if name then if lld.line_length > 850 then diff --git a/src/nvim/generators/hashy.lua b/src/nvim/generators/hashy.lua index b10bafb9f9..711e695742 100644 --- a/src/nvim/generators/hashy.lua +++ b/src/nvim/generators/hashy.lua @@ -3,7 +3,6 @@ local M = {} _G.d = M - local function setdefault(table, key) local val = table[key] if val == nil then @@ -16,28 +15,30 @@ end function M.build_pos_hash(strings) local len_buckets = {} local maxlen = 0 - for _,s in ipairs(strings) do - table.insert(setdefault(len_buckets, #s),s) - if #s > maxlen then maxlen = #s end + for _, s in ipairs(strings) do + table.insert(setdefault(len_buckets, #s), s) + if #s > maxlen then + maxlen = #s + end end local len_pos_buckets = {} local worst_buck_size = 0 - for len = 1,maxlen do + for len = 1, maxlen do local strs = len_buckets[len] if strs then -- the best position so far generates `best_bucket` -- with `minsize` worst case collisions - local bestpos, minsize, best_bucket = nil, #strs*2, nil - for pos = 1,len do + local bestpos, minsize, best_bucket = nil, #strs * 2, nil + for pos = 1, len do local try_bucket = {} - for _,str in ipairs(strs) do + for _, str in ipairs(strs) do local poschar = string.sub(str, pos, pos) table.insert(setdefault(try_bucket, poschar), str) end local maxsize = 1 - for _,pos_strs in pairs(try_bucket) do + for _, pos_strs in pairs(try_bucket) do maxsize = math.max(maxsize, #pos_strs) end if maxsize < minsize then @@ -46,7 +47,7 @@ function M.build_pos_hash(strings) best_bucket = try_bucket end end - len_pos_buckets[len] = {bestpos, best_bucket} + len_pos_buckets[len] = { bestpos, best_bucket } worst_buck_size = math.max(worst_buck_size, minsize) end end @@ -55,73 +56,79 @@ end function M.switcher(put, tab, maxlen, worst_buck_size) local neworder = {} - put " switch (len) {\n" + put ' switch (len) {\n' local bucky = worst_buck_size > 1 - for len = 1,maxlen do + for len = 1, maxlen do local vals = tab[len] if vals then - put(" case "..len..": ") + put(' case ' .. len .. ': ') local pos, posbuck = unpack(vals) local keys = vim.tbl_keys(posbuck) if #keys > 1 then table.sort(keys) - put("switch (str["..(pos-1).."]) {\n") - for _,c in ipairs(keys) do + put('switch (str[' .. (pos - 1) .. ']) {\n') + for _, c in ipairs(keys) do local buck = posbuck[c] local startidx = #neworder vim.list_extend(neworder, buck) local endidx = #neworder - put(" case '"..c.."': ") - put("low = "..startidx.."; ") - if bucky then put("high = "..endidx.."; ") end - put "break;\n" + put(" case '" .. c .. "': ") + put('low = ' .. startidx .. '; ') + if bucky then + put('high = ' .. endidx .. '; ') + end + put 'break;\n' end - put " default: break;\n" - put " }\n " + put ' default: break;\n' + put ' }\n ' else - local startidx = #neworder - table.insert(neworder, posbuck[keys[1]][1]) - local endidx = #neworder - put("low = "..startidx.."; ") - if bucky then put("high = "..endidx.."; ") end + local startidx = #neworder + table.insert(neworder, posbuck[keys[1]][1]) + local endidx = #neworder + put('low = ' .. startidx .. '; ') + if bucky then + put('high = ' .. endidx .. '; ') + end end - put "break;\n" + put 'break;\n' end end - put " default: break;\n" - put " }\n" + put ' default: break;\n' + put ' }\n' return neworder end function M.hashy_hash(name, strings, access) local stats = {} - local put = function(str) table.insert(stats, str) end + local put = function(str) + table.insert(stats, str) + end local len_pos_buckets, maxlen, worst_buck_size = M.build_pos_hash(strings) - put("int "..name.."_hash(const char *str, size_t len)\n{\n") + put('int ' .. name .. '_hash(const char *str, size_t len)\n{\n') if worst_buck_size > 1 then - put(" int low = 0, high = 0;\n") + put(' int low = 0, high = 0;\n') else - put(" int low = -1;\n") + put(' int low = -1;\n') end local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size) if worst_buck_size > 1 then - put ([[ + put([[ for (int i = low; i < high; i++) { - if (!memcmp(str, ]]..access("i")..[[, len)) { + if (!memcmp(str, ]] .. access('i') .. [[, len)) { return i; } } return -1; ]]) else - put ([[ - if (low < 0 || memcmp(str, ]]..access("low")..[[, len)) { + put([[ + if (low < 0 || memcmp(str, ]] .. access('low') .. [[, len)) { return -1; } return low; ]]) end - put "}\n\n" + put '}\n\n' return neworder, table.concat(stats) end diff --git a/src/nvim/generators/preload.lua b/src/nvim/generators/preload.lua index 4b7fde2c39..721d2880b8 100644 --- a/src/nvim/generators/preload.lua +++ b/src/nvim/generators/preload.lua @@ -1,7 +1,7 @@ local srcdir = table.remove(arg, 1) local nlualib = table.remove(arg, 1) -package.path = srcdir .. '/src/nvim/?.lua;' ..srcdir .. '/runtime/lua/?.lua;' .. package.path -_G.vim = require'vim.shared' +package.path = srcdir .. '/src/nvim/?.lua;' .. srcdir .. '/runtime/lua/?.lua;' .. package.path +_G.vim = require 'vim.shared' _G.vim.inspect = require 'vim.inspect' package.cpath = package.cpath .. ';' .. nlualib require 'nlua0' -- cgit From 3159a2c28f5ea8797cb525c74dedd622bfe4a0a1 Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Tue, 5 Dec 2023 09:40:48 +0900 Subject: fix(change): update fold after on_bytes (#26364) Problem: With vim.treesitter.foldexpr, `o`-ing two lines above a folded region opens the fold. This does not happen with legacy foldexprs. For example, make a markdown file with the following text (without indentation), enable treesitter fold, and follow the instruction in the text. put cursor on this line and type zoo initially folded, revealed by zo # then this fold will be opened initially folded, revealed by o Analysis: * `o` updates folds first (done in `changed_lines`), evaluating foldexpr, and then invokes `on_bytes` (done in `extmark_splice`). * Treesitter fold allocates the foldinfo for added lines (`add_range`) on `on_bytes`. * Therefore, when treesitter foldexpr is invoked while running `o`, it sees outdated foldinfo. Solution: `extmark_splice`, and then `changed_lines`. This seems to be the standard order in other places, e.g., `nvim_buf_set_lines`. --- src/nvim/change.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/change.c b/src/nvim/change.c index efc2db1413..c528ffba20 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -1839,11 +1839,11 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) curwin->w_cursor.lnum = old_cursor.lnum + 1; } if (did_append) { - changed_lines(curbuf, curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1, true); // 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); + changed_lines(curbuf, curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1, true); } curbuf_splice_pending--; -- cgit From 0b74ad0a641f28d9d3da5353e98372d87078bd9d Mon Sep 17 00:00:00 2001 From: Riccardo Mazzarini Date: Tue, 5 Dec 2023 12:33:57 +0100 Subject: refactor(api): complete conversion from `Dictionary` to `Dict(opts)` (#26365) --- src/nvim/api/buffer.c | 110 +++++++++++++------------------------------- src/nvim/api/command.c | 6 +-- src/nvim/api/deprecated.c | 7 +-- src/nvim/api/deprecated.h | 1 + src/nvim/api/extmark.c | 26 ++--------- src/nvim/api/keysets_defs.h | 32 +++++++++++++ src/nvim/api/vim.c | 27 +++-------- 7 files changed, 79 insertions(+), 130 deletions(-) (limited to 'src') diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 9d0ac5d6ef..e0dd265167 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -152,7 +152,7 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err) /// @return False if attach failed (invalid parameter, or buffer isn't loaded); /// otherwise True. TODO: LUA_API_NO_EVAL Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, - DictionaryOf(LuaRef) opts, Error *err) + Dict(buf_attach) *opts, Error *err) FUNC_API_SINCE(4) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -161,64 +161,40 @@ Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, return false; } - bool is_lua = (channel_id == LUA_INTERNAL_CALL); BufUpdateCallbacks cb = BUF_UPDATE_CALLBACKS_INIT; - struct { - const char *name; - LuaRef *dest; - } cbs[] = { - { "on_lines", &cb.on_lines }, - { "on_bytes", &cb.on_bytes }, - { "on_changedtick", &cb.on_changedtick }, - { "on_detach", &cb.on_detach }, - { "on_reload", &cb.on_reload }, - { NULL, NULL }, - }; - - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object *v = &opts.items[i].value; - bool key_used = false; - if (is_lua) { - for (size_t j = 0; cbs[j].name; j++) { - if (strequal(cbs[j].name, k.data)) { - VALIDATE_T(cbs[j].name, kObjectTypeLuaRef, v->type, { - goto error; - }); - *(cbs[j].dest) = v->data.luaref; - v->data.luaref = LUA_NOREF; - key_used = true; - break; - } - } - if (key_used) { - continue; - } else if (strequal("utf_sizes", k.data)) { - VALIDATE_T("utf_sizes", kObjectTypeBoolean, v->type, { - goto error; - }); - cb.utf_sizes = v->data.boolean; - key_used = true; - } else if (strequal("preview", k.data)) { - VALIDATE_T("preview", kObjectTypeBoolean, v->type, { - goto error; - }); - cb.preview = v->data.boolean; - key_used = true; - } + if (channel_id == LUA_INTERNAL_CALL) { + if (HAS_KEY(opts, buf_attach, on_lines)) { + cb.on_lines = opts->on_lines; + opts->on_lines = LUA_NOREF; } - VALIDATE_S(key_used, "'opts' key", k.data, { - goto error; - }); + if (HAS_KEY(opts, buf_attach, on_bytes)) { + cb.on_bytes = opts->on_bytes; + opts->on_bytes = LUA_NOREF; + } + + if (HAS_KEY(opts, buf_attach, on_changedtick)) { + cb.on_changedtick = opts->on_changedtick; + opts->on_changedtick = LUA_NOREF; + } + + if (HAS_KEY(opts, buf_attach, on_detach)) { + cb.on_detach = opts->on_detach; + opts->on_detach = LUA_NOREF; + } + + if (HAS_KEY(opts, buf_attach, on_reload)) { + cb.on_reload = opts->on_reload; + opts->on_reload = LUA_NOREF; + } + + cb.utf_sizes = opts->utf_sizes; + + cb.preview = opts->preview; } return buf_updates_register(buf, channel_id, cb, send_buffer); - -error: - buffer_update_callbacks_free(cb); - return false; } /// Deactivates buffer-update events on the channel. @@ -781,16 +757,12 @@ early_end: ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer, Integer start_row, Integer start_col, Integer end_row, Integer end_col, - Dictionary opts, lua_State *lstate, + Dict(empty) *opts, lua_State *lstate, Error *err) FUNC_API_SINCE(9) { Array rv = ARRAY_DICT_INIT; - VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { - return rv; - }); - buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { @@ -1081,7 +1053,7 @@ Boolean nvim_buf_is_loaded(Buffer buffer) /// @param opts Optional parameters. Keys: /// - force: Force deletion and ignore unsaved changes. /// - unload: Unloaded only, do not delete. See |:bunload| -void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err) +void nvim_buf_delete(Buffer buffer, Dict(buf_delete) *opts, Error *err) FUNC_API_SINCE(7) FUNC_API_TEXTLOCK { @@ -1091,25 +1063,9 @@ void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err) return; } - bool force = false; - bool unload = false; - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object v = opts.items[i].value; - if (strequal("force", k.data)) { - force = api_object_to_bool(v, "force", false, err); - } else if (strequal("unload", k.data)) { - unload = api_object_to_bool(v, "unload", false, err); - } else { - VALIDATE_S(false, "'opts' key", k.data, { - return; - }); - } - } + bool force = opts->force; - if (ERROR_SET(err)) { - return; - } + bool unload = opts->unload; int result = do_buffer(unload ? DOBUF_UNLOAD : DOBUF_WIPE, DOBUF_FIRST, @@ -1193,7 +1149,7 @@ Boolean nvim_buf_del_mark(Buffer buffer, String name, Error *err) /// @return true if the mark was set, else false. /// @see |nvim_buf_del_mark()| /// @see |nvim_buf_get_mark()| -Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, Dictionary opts, +Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, Dict(empty) *opts, Error *err) FUNC_API_SINCE(8) { diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 7116f4bce0..abb589ecdf 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -94,15 +94,11 @@ /// - "belowright": |:belowright|. /// - "topleft": |:topleft|. /// - "botright": |:botright|. -Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err) +Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err) FUNC_API_SINCE(10) FUNC_API_FAST { Dictionary result = ARRAY_DICT_INIT; - VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { - return result; - }); - // Parse command line exarg_T ea; CmdParseInfo cmdinfo; diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 11795033cc..d6a76617a7 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -126,7 +126,7 @@ void nvim_buf_clear_highlight(Buffer buffer, Integer ns_id, Integer line_start, /// @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) + Dict(empty) *opts, Error *err) FUNC_API_SINCE(5) FUNC_API_DEPRECATED_SINCE(8) { @@ -140,11 +140,6 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A return 0; } - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); - return 0; - } - uint32_t ns_id = src2ns(&src_id); int width; diff --git a/src/nvim/api/deprecated.h b/src/nvim/api/deprecated.h index e20d8304e0..c879794bb3 100644 --- a/src/nvim/api/deprecated.h +++ b/src/nvim/api/deprecated.h @@ -2,6 +2,7 @@ #include // IWYU pragma: keep +#include "nvim/api/keysets_defs.h" // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index 80b1546329..ec47d7227e 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -187,7 +187,7 @@ static Array extmark_to_array(MTPair extmark, bool id, bool add_dict, bool hl_na /// @return 0-indexed (row, col) tuple or empty list () if extmark id was /// absent ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, - Integer id, Dictionary opts, + Integer id, Dict(get_extmark) *opts, Error *err) FUNC_API_SINCE(7) { @@ -203,27 +203,9 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, return rv; }); - bool details = false; - bool hl_name = true; - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object *v = &opts.items[i].value; - if (strequal("details", k.data)) { - details = api_object_to_bool(*v, "details", false, err); - if (ERROR_SET(err)) { - return rv; - } - } else if (strequal("hl_name", k.data)) { - hl_name = api_object_to_bool(*v, "hl_name", false, err); - if (ERROR_SET(err)) { - return rv; - } - } else { - VALIDATE_S(false, "'opts' key", k.data, { - return rv; - }); - } - } + bool details = opts->details; + + bool hl_name = GET_BOOL_OR_TRUE(opts, get_extmark, hl_name); MTPair extmark = extmark_from_id(buf, (uint32_t)ns_id, (uint32_t)id); if (extmark.start.pos.row < 0) { diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index e59eda5686..5aae88f7b3 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -51,6 +51,12 @@ typedef struct { Boolean undo_restore; } Dict(set_extmark); +typedef struct { + OptionalKeys is_set__get_extmark_; + Boolean details; + Boolean hl_name; +} Dict(get_extmark); + typedef struct { OptionalKeys is_set__get_extmarks_; Integer limit; @@ -313,3 +319,29 @@ typedef struct { typedef struct { Boolean output; } Dict(exec_opts); + +typedef struct { + OptionalKeys is_set__buf_attach_; + LuaRef on_lines; + LuaRef on_bytes; + LuaRef on_changedtick; + LuaRef on_detach; + LuaRef on_reload; + Boolean utf_sizes; + Boolean preview; +} Dict(buf_attach); + +typedef struct { + OptionalKeys is_set__buf_delete_; + Boolean force; + Boolean unload; +} Dict(buf_delete); + +typedef struct { + OptionalKeys is_set__empty_; +} Dict(empty); + +typedef struct { + OptionalKeys is_set__open_term_; + LuaRef on_input; +} Dict(open_term); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index db08cb8cf0..0842469c59 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -987,7 +987,7 @@ fail: /// ["input", term, bufnr, data] /// @param[out] err Error details, if any /// @return Channel id, or 0 on error -Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) +Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) FUNC_API_SINCE(7) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { @@ -1002,19 +1002,10 @@ Integer nvim_open_term(Buffer buffer, DictionaryOf(LuaRef) opts, Error *err) } LuaRef cb = LUA_NOREF; - for (size_t i = 0; i < opts.size; i++) { - String k = opts.items[i].key; - Object *v = &opts.items[i].value; - if (strequal("on_input", k.data)) { - VALIDATE_T("on_input", kObjectTypeLuaRef, v->type, { - return 0; - }); - cb = v->data.luaref; - v->data.luaref = LUA_NOREF; - break; - } else { - VALIDATE_S(false, "'opts' key", k.data, {}); - } + + if (HAS_KEY(opts, open_term, on_input)) { + cb = opts->on_input; + opts->on_input = LUA_NOREF; } Channel *chan = channel_alloc(kChannelStreamInternal); @@ -1941,14 +1932,10 @@ Object nvim_get_proc(Integer pid, Error *err) /// @param finish Finish the completion and dismiss the popup menu. Implies {insert}. /// @param opts Optional parameters. Reserved for future use. /// @param[out] err Error details, if any -void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts, +void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dict(empty) *opts, Error *err) FUNC_API_SINCE(6) { - VALIDATE((opts.size == 0), "%s", "opts dict isn't empty", { - return; - }); - if (finish) { insert = true; } @@ -2049,7 +2036,7 @@ Boolean nvim_del_mark(String name, Error *err) /// not set. /// @see |nvim_buf_set_mark()| /// @see |nvim_del_mark()| -Array nvim_get_mark(String name, Dictionary opts, Error *err) +Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) FUNC_API_SINCE(8) { Array rv = ARRAY_DICT_INIT; -- cgit From 14572727261278e5bf68080c9369a8507f3d564f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 5 Dec 2023 20:05:12 +0800 Subject: refactor(IWYU): move marktree types to marktree_defs.h (#26402) --- src/clint.py | 5 --- src/nvim/api/buffer.c | 1 + src/nvim/api/keysets_defs.h | 8 ++--- src/nvim/autocmd.h | 6 ++-- src/nvim/buffer_defs.h | 2 +- src/nvim/decoration.c | 1 + src/nvim/decoration.h | 2 +- src/nvim/extmark.h | 8 ++--- src/nvim/marktree.c | 15 +++++--- src/nvim/marktree.h | 83 ++------------------------------------------- src/nvim/marktree_defs.h | 83 +++++++++++++++++++++++++++++++++++++++++++++ src/nvim/plines.c | 1 + src/nvim/plines.h | 4 +-- 13 files changed, 112 insertions(+), 107 deletions(-) create mode 100644 src/nvim/marktree_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 596e2d8a26..ed5aaf43d2 100755 --- a/src/clint.py +++ b/src/clint.py @@ -900,16 +900,13 @@ def CheckIncludes(filename, lines, error): # These should be synced with the ignored headers in the `iwyu` target in # the Makefile. check_includes_ignore = [ - "src/nvim/api/extmark.h", "src/nvim/api/private/helpers.h", "src/nvim/api/private/validate.h", "src/nvim/assert_defs.h", - "src/nvim/autocmd.h", "src/nvim/buffer.h", "src/nvim/buffer_defs.h", "src/nvim/channel.h", "src/nvim/charset.h", - "src/nvim/decoration.h", "src/nvim/drawline.h", "src/nvim/eval.h", "src/nvim/eval/encode.h", @@ -927,7 +924,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/event/stream.h", "src/nvim/event/time.h", "src/nvim/event/wstream.h", - "src/nvim/extmark.h", "src/nvim/garray.h", "src/nvim/globals.h", "src/nvim/grid.h", @@ -946,7 +942,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/os/pty_conpty_win.h", "src/nvim/os/pty_process_unix.h", "src/nvim/os/pty_process_win.h", - "src/nvim/plines.h", "src/nvim/tui/input.h", "src/nvim/ui.h", "src/nvim/viml/parser/expressions.h", diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index e0dd265167..99d261e73d 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -12,6 +12,7 @@ #include "nvim/api/buffer.h" #include "nvim/api/keysets_defs.h" #include "nvim/api/private/defs.h" +#include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/ascii_defs.h" diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index 5aae88f7b3..d1cbe43de0 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -2,6 +2,10 @@ #include "nvim/api/private/defs.h" +typedef struct { + OptionalKeys is_set__empty_; +} Dict(empty); + typedef struct { OptionalKeys is_set__context_; Array types; @@ -337,10 +341,6 @@ typedef struct { Boolean unload; } Dict(buf_delete); -typedef struct { - OptionalKeys is_set__empty_; -} Dict(empty); - typedef struct { OptionalKeys is_set__open_term_; LuaRef on_input; diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index 8ff4d75ddf..ea8f32feb2 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -1,9 +1,10 @@ #pragma once #include -#include -#include +#include // IWYU pragma: keep +#include // IWYU pragma: keep +#include "klib/kvec.h" #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/autocmd_defs.h" // IWYU pragma: export #include "nvim/buffer_defs.h" @@ -12,7 +13,6 @@ #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/pos_defs.h" -#include "nvim/types_defs.h" // Set by the apply_autocmds_group function if the given event is equal to // EVENT_FILETYPE. Used by the readfile function in order to determine if diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index b26d42385b..7402e66403 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -26,7 +26,7 @@ typedef struct { #include "nvim/map_defs.h" #include "nvim/mapping_defs.h" #include "nvim/mark_defs.h" -#include "nvim/marktree.h" +#include "nvim/marktree_defs.h" #include "nvim/option_vars.h" #include "nvim/pos_defs.h" #include "nvim/statusline_defs.h" diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 11204a1b31..ccba8bd607 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -14,6 +14,7 @@ #include "nvim/grid.h" #include "nvim/highlight.h" #include "nvim/highlight_group.h" +#include "nvim/marktree.h" #include "nvim/memory.h" #include "nvim/move.h" #include "nvim/option_vars.h" diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index e5bac169dc..92e0cbc76b 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -8,7 +8,7 @@ #include "nvim/buffer_defs.h" #include "nvim/decoration_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" -#include "nvim/marktree.h" +#include "nvim/marktree_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index 1a7a1ddeff..5ba079bd12 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -1,17 +1,15 @@ #pragma once #include -#include #include #include "klib/kvec.h" -#include "nvim/buffer_defs.h" -#include "nvim/decoration.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/decoration_defs.h" // IWYU pragma: keep #include "nvim/extmark_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" -#include "nvim/marktree.h" +#include "nvim/marktree_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" -#include "nvim/types_defs.h" EXTERN int curbuf_splice_pending INIT( = 0); diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index f14da1b605..fa5e7dcbe2 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -50,15 +50,15 @@ #include #include "klib/kvec.h" -#include "nvim/garray.h" +#include "nvim/macros_defs.h" +#include "nvim/map_defs.h" #include "nvim/marktree.h" #include "nvim/memory.h" #include "nvim/pos_defs.h" // only for debug functions #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" -#include "nvim/garray_defs.h" -#include "nvim/macros_defs.h" +#include "nvim/garray.h" #define T MT_BRANCH_FACTOR #define ILEN (sizeof(MTNode) + (2 * T) * sizeof(void *)) @@ -2200,7 +2200,12 @@ String mt_inspect(MarkTree *b, bool keys, bool dot) return ga_take_string(ga); } -void mt_inspect_node(MarkTree *b, garray_T *ga, bool keys, MTNode *n, MTPos off) +static inline uint64_t mt_dbg_id(uint64_t id) +{ + return (id >> 1) & 0xffffffff; +} + +static void mt_inspect_node(MarkTree *b, garray_T *ga, bool keys, MTNode *n, MTPos off) { static char buf[1024]; GA_PUT("["); @@ -2240,7 +2245,7 @@ void mt_inspect_node(MarkTree *b, garray_T *ga, bool keys, MTNode *n, MTPos off) ga_concat(ga, "]"); } -void mt_inspect_dotfile_node(MarkTree *b, garray_T *ga, MTNode *n, MTPos off, char *parent) +static void mt_inspect_dotfile_node(MarkTree *b, garray_T *ga, MTNode *n, MTPos off, char *parent) { static char buf[1024]; char namebuf[64]; diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h index c76359d3f9..46d60a2b69 100644 --- a/src/nvim/marktree.h +++ b/src/nvim/marktree.h @@ -1,69 +1,15 @@ #pragma once #include -#include +#include // IWYU pragma: keep #include -#include "klib/kvec.h" #include "nvim/decoration_defs.h" -#include "nvim/garray_defs.h" // IWYU pragma: keep -#include "nvim/map_defs.h" +#include "nvim/marktree_defs.h" // IWYU pragma: export #include "nvim/pos_defs.h" // IWYU pragma: keep // only for debug functions: #include "nvim/api/private/defs.h" // IWYU pragma: keep -#define MT_MAX_DEPTH 20 -#define MT_BRANCH_FACTOR 10 -// note max branch is actually 2*MT_BRANCH_FACTOR -// and strictly this is ceil(log2(2*MT_BRANCH_FACTOR + 1)) -// as we need a pseudo-index for "right before this node" -#define MT_LOG2_BRANCH 5 - -typedef struct { - int32_t row; - int32_t col; -} MTPos; -#define MTPos(r, c) ((MTPos){ .row = (r), .col = (c) }) - -typedef struct mtnode_s MTNode; - -typedef struct { - MTPos pos; - int lvl; - MTNode *x; - int i; - struct { - int oldcol; - int i; - } s[MT_MAX_DEPTH]; - - size_t intersect_idx; - MTPos intersect_pos; - MTPos intersect_pos_x; -} MarkTreeIter; - -#define marktree_itr_valid(itr) ((itr)->x != NULL) -// access raw key: flags in MT_FLAG_EXTERNAL_MASK and decor_data are safe to modify. -#define mt_itr_rawkey(itr) ((itr)->x->key[(itr)->i]) - -// Internal storage -// -// NB: actual marks have flags > 0, so we can use (row,col,0) pseudo-key for -// "space before (row,col)" -typedef struct { - MTPos pos; - uint32_t ns; - uint32_t id; - uint16_t flags; - DecorInlineData decor_data; // "ext" tag in flags -} MTKey; - -typedef struct { - MTKey start; - MTPos end_pos; - bool end_right_gravity; -} MTPair; - #define MT_INVALID_KEY (MTKey) { { -1, -1 }, 0, 0, 0, { .hl = DECOR_HIGHLIGHT_INLINE_INIT } } #define MT_FLAG_REAL (((uint16_t)1) << 0) @@ -179,31 +125,6 @@ static inline DecorInline mt_decor(MTKey key) return (DecorInline){ .ext = key.flags & MT_FLAG_DECOR_EXT, .data = key.decor_data }; } -typedef kvec_withinit_t(uint64_t, 4) Intersection; - -struct mtnode_s { - int32_t n; - int16_t level; - int16_t p_idx; // index in parent - Intersection intersect; - // TODO(bfredl): we could consider having a only-sometimes-valid - // index into parent for faster "cached" lookup. - MTNode *parent; - MTKey key[2 * MT_BRANCH_FACTOR - 1]; - MTNode *ptr[]; -}; - -static inline uint64_t mt_dbg_id(uint64_t id) -{ - return (id>>1)&0xffffffff; -} - -typedef struct { - MTNode *root; - size_t n_keys, n_nodes; - PMap(uint64_t) id2node[1]; -} MarkTree; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "marktree.h.generated.h" #endif diff --git a/src/nvim/marktree_defs.h b/src/nvim/marktree_defs.h new file mode 100644 index 0000000000..8aa1b1e376 --- /dev/null +++ b/src/nvim/marktree_defs.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include + +#include "klib/kvec.h" +#include "nvim/decoration_defs.h" +#include "nvim/map_defs.h" + +enum { + MT_MAX_DEPTH = 20, + MT_BRANCH_FACTOR = 10, + // note max branch is actually 2*MT_BRANCH_FACTOR + // and strictly this is ceil(log2(2*MT_BRANCH_FACTOR + 1)) + // as we need a pseudo-index for "right before this node" + MT_LOG2_BRANCH = 5, +}; + +typedef struct { + int32_t row; + int32_t col; +} MTPos; +#define MTPos(r, c) ((MTPos){ .row = (r), .col = (c) }) + +typedef struct mtnode_s MTNode; + +typedef struct { + MTPos pos; + int lvl; + MTNode *x; + int i; + struct { + int oldcol; + int i; + } s[MT_MAX_DEPTH]; + + size_t intersect_idx; + MTPos intersect_pos; + MTPos intersect_pos_x; +} MarkTreeIter; + +#define marktree_itr_valid(itr) ((itr)->x != NULL) +// access raw key: flags in MT_FLAG_EXTERNAL_MASK and decor_data are safe to modify. +#define mt_itr_rawkey(itr) ((itr)->x->key[(itr)->i]) + +// Internal storage +// +// NB: actual marks have flags > 0, so we can use (row,col,0) pseudo-key for +// "space before (row,col)" +typedef struct { + MTPos pos; + uint32_t ns; + uint32_t id; + uint16_t flags; + DecorInlineData decor_data; // "ext" tag in flags +} MTKey; + +typedef struct { + MTKey start; + MTPos end_pos; + bool end_right_gravity; +} MTPair; + +typedef kvec_withinit_t(uint64_t, 4) Intersection; + +struct mtnode_s { + int32_t n; + int16_t level; + int16_t p_idx; // index in parent + Intersection intersect; + // TODO(bfredl): we could consider having a only-sometimes-valid + // index into parent for faster "cached" lookup. + MTNode *parent; + MTKey key[2 * MT_BRANCH_FACTOR - 1]; + MTNode *ptr[]; +}; + +typedef struct { + MTNode *root; + size_t n_keys, n_nodes; + PMap(uint64_t) id2node[1]; +} MarkTree; diff --git a/src/nvim/plines.c b/src/nvim/plines.c index fbddb1ab4a..cbfaa4ace3 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -14,6 +14,7 @@ #include "nvim/indent.h" #include "nvim/macros_defs.h" #include "nvim/mark.h" +#include "nvim/marktree.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/move.h" diff --git a/src/nvim/plines.h b/src/nvim/plines.h index 6aede88c8b..7227db4524 100644 --- a/src/nvim/plines.h +++ b/src/nvim/plines.h @@ -1,10 +1,10 @@ #pragma once #include -#include +#include // IWYU pragma: keep #include "nvim/buffer_defs.h" -#include "nvim/marktree.h" +#include "nvim/marktree_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep /// Argument for lbr_chartabsize(). -- cgit From 27501d3b6a8d577cf3f5ecc3fe9e219f477586b7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 5 Dec 2023 12:52:06 -0800 Subject: test: fileio_spec is unreliable/flaky #26404 Problem: CI sometimes fails. Something is triggering an extra fsync(). FAILED test/functional/core/fileio_spec.lua @ 52: fileio fsync() codepaths #8304 test/functional/core/fileio_spec.lua:87: Expected objects to be the same. Passed in: (number) 3 Expected: (number) 2 stack traceback: test/functional/core/fileio_spec.lua:87: in function Solution: Relax the assertion to `fsync >= 2` instead of exactly 2. (Note this is not a behavior change: the next assertion has always checked `fsync == 4`, it's just that the intermediate 3rd fsync was never explicitly asserted.) --- src/nvim/globals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 1299aa12e5..19e5c5a4a6 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -672,7 +672,7 @@ EXTERN bool must_redraw_pum INIT( = false); // redraw pum. NB: must_redraw EXTERN bool need_highlight_changed INIT( = true); -EXTERN FILE *scriptout INIT( = NULL); ///< Stream to write script to. +EXTERN FILE *scriptout INIT( = NULL); ///< Write input to this file ("nvim -w"). // Note that even when handling SIGINT, volatile is not necessary because the // callback is not called directly from the signal handlers. -- cgit From 06ff540e1ca25f4c26670f184d4087f6e3188064 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 6 Dec 2023 07:16:02 +0800 Subject: vim-patch:9.0.2151: 'breakindent' is not drawn after diff filler lines (#26412) Problem: 'breakindent' is not drawn after diff filler lines. Solution: Correct check for whether 'breakindent' should be drawn. closes: vim/vim#13624 https://github.com/vim/vim/commit/588f20decebebedba3ad733f4f443a597e9747c3 Cherry-pick Test_diff_with_syntax() change from patch 9.0.1257. --- src/nvim/drawline.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index e0887ed1d0..77bd05eb55 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -704,8 +704,8 @@ static void handle_breakindent(win_T *wp, winlinevars_T *wlv) if (wlv->draw_state == WL_BRI - 1 && wlv->n_extra == 0) { wlv->draw_state = WL_BRI; // if wlv->need_showbreak is set, breakindent also applies - if (wp->w_p_bri && (wlv->row != wlv->startrow || wlv->need_showbreak) - && wlv->filler_lines == 0) { + if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines + || wlv->need_showbreak)) { wlv->char_attr = 0; if (wlv->diff_hlf != (hlf_T)0) { wlv->char_attr = win_hl_attr(wp, (int)wlv->diff_hlf); -- cgit From cc38086039853d53157b30fec41babb148399038 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 6 Dec 2023 01:04:21 +0100 Subject: docs: small fixes (#26243) Co-authored-by: umlx5h Co-authored-by: Gregory Anders Co-authored-by: Evan Farrar --- src/nvim/message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index 219532e45e..b9935d5b5d 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2833,7 +2833,7 @@ static int do_more_prompt(int typed_char) } else { // redisplay all lines // TODO(bfredl): this case is not optimized (though only concerns - // event fragmentization, not unnecessary scroll events). + // event fragmentation, not unnecessary scroll events). grid_fill(&msg_grid_adj, 0, Rows, 0, Columns, ' ', ' ', HL_ATTR(HLF_MSG)); for (int i = 0; mp != NULL && i < Rows - 1; i++) { -- cgit From e718866358652020e57fdb43bd9322f0c5732432 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 6 Dec 2023 13:39:36 +0600 Subject: refactor(options): remove SOPT type enums (#26417) Problem: SOPT type enums (`SOPT_NUM`, `SOPT_BOOL`, `SOPT_STRING`) are no longer used anywhere. Solution: Remove them. --- src/nvim/api/options.c | 10 +--------- src/nvim/option.h | 9 +++------ 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 9cf91bad42..ef7c11131a 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -400,7 +400,7 @@ int get_option_attrs(char *name) vimoption_T *opt = get_option(opt_idx); if (is_tty_option(opt->fullname)) { - return SOPT_STRING | SOPT_GLOBAL; + return SOPT_GLOBAL; } // Hidden option @@ -410,14 +410,6 @@ int get_option_attrs(char *name) int attrs = 0; - if (opt->flags & P_BOOL) { - attrs |= SOPT_BOOL; - } else if (opt->flags & P_NUM) { - attrs |= SOPT_NUM; - } else if (opt->flags & P_STRING) { - attrs |= SOPT_STRING; - } - if (opt->indir == PV_NONE || (opt->indir & PV_BOTH)) { attrs |= SOPT_GLOBAL; } diff --git a/src/nvim/option.h b/src/nvim/option.h index ebf8e0417d..780f359f5d 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -89,12 +89,9 @@ typedef enum { /// Return value from get_option_value_strict enum { - SOPT_BOOL = 0x01, ///< Boolean option - SOPT_NUM = 0x02, ///< Number option - SOPT_STRING = 0x04, ///< String option - SOPT_GLOBAL = 0x08, ///< Option has global value - SOPT_WIN = 0x10, ///< Option has window-local value - SOPT_BUF = 0x20, ///< Option has buffer-local value + SOPT_GLOBAL = 0x01, ///< Option has global value + SOPT_WIN = 0x02, ///< Option has window-local value + SOPT_BUF = 0x04, ///< Option has buffer-local value }; // OptVal helper macros. -- cgit From 401ce9f3fdebed05a929de1b94e55c74d45e2ffb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 6 Dec 2023 15:48:16 +0800 Subject: vim-patch:8.1.1583: set_ref_in_list() only sets ref in items (#26418) Problem: Set_ref_in_list() only sets ref in items. Solution: Rename to set_ref_in_list_items() to avoid confusion. https://github.com/vim/vim/commit/7be3ab25891fec711d8a2d9d242711a9155852b6 Omit set_ref_in_list() and set_ref_in_dict(): only used in popup window, if_pyth and if_lua. Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 4 ++-- src/nvim/eval/userfunc.c | 4 ++-- src/nvim/shada.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ae34f5715f..3ce6e98539 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4711,7 +4711,7 @@ bool set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack) /// @param ht_stack Used to add hashtabs to be marked. Can be NULL. /// /// @returns true if setting references failed somehow. -bool set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack) +bool set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack) FUNC_ATTR_WARN_UNUSED_RESULT { bool abort = false; @@ -4788,7 +4788,7 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack // Didn't see this list yet. ll->lv_copyID = copyID; if (list_stack == NULL) { - abort = set_ref_in_list(ll, copyID, ht_stack); + abort = set_ref_in_list_items(ll, copyID, ht_stack); } else { list_stack_T *const newitem = xmalloc(sizeof(list_stack_T)); newitem->list = ll; diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index e0bf30b158..ebc84922cb 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -3818,7 +3818,7 @@ bool set_ref_in_previous_funccal(int copyID) fc->fc_copyID = copyID + 1; if (set_ref_in_ht(&fc->fc_l_vars.dv_hashtab, copyID + 1, NULL) || set_ref_in_ht(&fc->fc_l_avars.dv_hashtab, copyID + 1, NULL) - || set_ref_in_list(&fc->fc_l_varlist, copyID + 1, NULL)) { + || set_ref_in_list_items(&fc->fc_l_varlist, copyID + 1, NULL)) { return true; } } @@ -3831,7 +3831,7 @@ static bool set_ref_in_funccal(funccall_T *fc, int copyID) fc->fc_copyID = copyID; if (set_ref_in_ht(&fc->fc_l_vars.dv_hashtab, copyID, NULL) || set_ref_in_ht(&fc->fc_l_avars.dv_hashtab, copyID, NULL) - || set_ref_in_list(&fc->fc_l_varlist, copyID, NULL) + || set_ref_in_list_items(&fc->fc_l_varlist, copyID, NULL) || set_ref_in_func(NULL, fc->fc_func, copyID)) { return true; } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 819fbcf885..02e7c3cc68 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -2604,7 +2604,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef case VAR_LIST: { list_T *l = vartv.vval.v_list; int copyID = get_copyID(); - if (!set_ref_in_list(l, copyID, NULL) + if (!set_ref_in_list_items(l, copyID, NULL) && copyID == l->lv_copyID) { tv_clear(&vartv); continue; -- cgit From f22e9e10f9ad77d2cce7f52837c5724877505a08 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 6 Dec 2023 16:49:40 +0800 Subject: vim-patch:8.2.3695: confusing error for missing key (#26420) Problem: Confusing error for missing key. Solution: Use the actualy key for the error. (closes vim/vim#9241) https://github.com/vim/vim/commit/5c1ec439f0a69e9aa7ece9bbb7d916f48f58be1e Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 6 +++++- src/nvim/globals.h | 1 + src/nvim/lua/executor.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 3ce6e98539..ac1461056c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3735,7 +3735,11 @@ static int eval_index_inner(typval_T *rettv, bool is_range, typval_T *var1, typv dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, key, keylen); if (item == NULL && verbose) { - semsg(_(e_dictkey), key); + if (keylen > 0) { + semsg(_(e_dictkey_len), keylen, key); + } else { + semsg(_(e_dictkey), key); + } } if (item == NULL || tv_is_luafunc(&item->di_tv)) { return FAIL; diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 19e5c5a4a6..c0fa63818e 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -887,6 +887,7 @@ EXTERN const char e_invalblob[] INIT(= N_("E978: Invalid operation for Blob")); EXTERN const char e_toomanyarg[] INIT(= N_("E118: Too many arguments for function: %s")); EXTERN const char e_toofewarg[] INIT(= N_("E119: Not enough arguments for function: %s")); EXTERN const char e_dictkey[] INIT(= N_("E716: Key not present in Dictionary: \"%s\"")); +EXTERN const char e_dictkey_len[] INIT(= N_("E716: Key not present in Dictionary: \"%.*s\"")); EXTERN const char e_listreq[] INIT(= N_("E714: List required")); EXTERN const char e_listblobreq[] INIT(= N_("E897: List or Blob required")); EXTERN const char e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary")); diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index d63a9a1307..e665732c1a 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -115,7 +115,7 @@ lua_State *get_global_lstate(void) /// Convert lua error into a Vim error message /// /// @param lstate Lua interpreter state. -/// @param[in] msg Message base, must contain one `%*s`. +/// @param[in] msg Message base, must contain one `%.*s`. void nlua_error(lua_State *const lstate, const char *const msg) FUNC_ATTR_NONNULL_ALL { -- cgit From 040369e1e4b86c4655a6885b36ee89ad4f10ca16 Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Mon, 4 Dec 2023 11:37:45 +0900 Subject: fix(treesitter): don't forcefully open folds Problem: When `vim._foldupdate()` is invoked inside a scheduled callback, the cursor may have moved to a line with a closed fold, e.g., after `dd` on the line that is one line above a folded region. Then it opens the fold, which is unnecessary and distracting. Legacy foldexprs do not have this issue. Solution: Don't explicitly open folds on cursor. Note: This doesn't completely prevent spurious opening of folds. That is due to bugs in treesitter foldexpr algorithm, which should be addressed separately. --- src/nvim/lua/stdlib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index d7a7abe3c8..fc2fedeaa1 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -536,11 +536,14 @@ static int nlua_iconv(lua_State *lstate) return 1; } -// Like 'zx' but don't call newFoldLevel() +// Update foldlevels (e.g., by evaluating 'foldexpr') for all lines in the current window without +// invoking other side effects. Unlike `zx`, it does not close manually opened folds and does not +// open folds under the cursor. static int nlua_foldupdate(lua_State *lstate) { curwin->w_foldinvalid = true; // recompute folds - foldOpenCursor(); + foldUpdate(curwin, 1, (linenr_T)MAXLNUM); + curwin->w_foldinvalid = false; return 0; } -- cgit From e057b38e7037808b3593fb1035794595b4e4a45e Mon Sep 17 00:00:00 2001 From: Emanuel Date: Wed, 6 Dec 2023 16:56:04 +0100 Subject: fix(json): allow objects with empty keys #25564 Problem: Empty string is a valid JSON key, but json_decode() treats an object with empty key as ":help msgpack-special-dict". #20757 :echo json_decode('{"": "1"}') {'_TYPE': [], '_VAL': [['', '1']]} Note: vim returns `{'': '1'}`. Solution: Allow empty string as an object key. Note that we still (currently) disallow empty keys in object_to_vim() (since 7c01d5ff9286d262097484c680e3a4eab49e2911): https://github.com/neovim/neovim/blob/f64e4b43e1191ff30d902730f752875aa55682ce/src/nvim/api/private/converter.c#L333-L334 Fix #20757 Co-authored-by: Justin M. Keyes --- src/nvim/eval.lua | 4 +--- src/nvim/eval/decode.c | 14 ++------------ 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 59423808be..51cf7bb0ea 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -5735,8 +5735,7 @@ M.funcs = { Vim value. In the following cases it will output |msgpack-special-dict|: 1. Dictionary contains duplicate key. - 2. Dictionary contains empty key. - 3. String contains NUL byte. Two special dictionaries: for + 2. String contains NUL byte. Two special dictionaries: for dictionary and for string will be emitted in case string with NUL byte was a dictionary key. @@ -7155,7 +7154,6 @@ M.funcs = { are binary strings). 2. String with NUL byte inside. 3. Duplicate key. - 4. Empty key. ext |List| with two values: first is a signed integer representing extension type. Second is |readfile()|-style list of strings. diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index a6407693d7..64b65b42a5 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -141,9 +141,7 @@ static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack ValuesStackItem key = kv_pop(*stack); if (last_container.special_val == NULL) { // These cases should have already been handled. - assert(!(key.is_special_string - || key.val.vval.v_string == NULL - || *key.val.vval.v_string == NUL)); + assert(!(key.is_special_string || key.val.vval.v_string == NULL)); dictitem_T *const obj_di = tv_dict_item_alloc(key.val.vval.v_string); tv_clear(&key.val); if (tv_dict_add(last_container.container.vval.v_dict, obj_di) @@ -170,11 +168,10 @@ static inline int json_decoder_pop(ValuesStackItem obj, ValuesStack *const stack tv_clear(&obj.val); return FAIL; } - // Handle empty key and key represented as special dictionary + // Handle special dictionaries if (last_container.special_val == NULL && (obj.is_special_string || obj.val.vval.v_string == NULL - || *obj.val.vval.v_string == NUL || tv_dict_find(last_container.container.vval.v_dict, obj.val.vval.v_string, -1))) { tv_clear(&obj.val); @@ -404,13 +401,6 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len, semsg(_("E474: Expected string end: %.*s"), (int)buf_len, buf); goto parse_json_string_fail; } - if (len == 0) { - POP(((typval_T) { - .v_type = VAR_STRING, - .vval = { .v_string = NULL }, - }), false); - goto parse_json_string_ret; - } char *str = xmalloc(len + 1); int fst_in_pair = 0; char *str_end = str; -- cgit From 2613ba5000d4c0d9b15e2eec2d2b97615575925e Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Tue, 5 Dec 2023 10:01:32 -0800 Subject: feat(defaults): enable 'termguicolors' by default when supported by terminal Enable 'termguicolors' automatically when Nvim can detect that truecolor is supported by the host terminal. If $COLORTERM is set to "truecolor" or "24bit", or the terminal's terminfo entry contains capabilities for Tc, RGB, or setrgbf and setrgbb, then we assume that the terminal supports truecolor. Otherwise, the terminal is queried (using both XTGETTCAP and SGR + DECRQSS). If the terminal's response to these queries (if any) indicates that it supports truecolor, then 'termguicolors' is enabled. --- src/nvim/options.lua | 4 ++++ src/nvim/tui/tui.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- src/nvim/ui_client.c | 9 +++++---- 3 files changed, 54 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index daaf73d241..50371b8bf3 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -8764,6 +8764,10 @@ return { Enables 24-bit RGB color in the |TUI|. Uses "gui" |:highlight| attributes instead of "cterm" attributes. |guifg| Requires an ISO-8613-3 compatible terminal. + + Nvim will automatically attempt to determine if the host terminal + supports 24-bit color and will enable this option if it does + (unless explicitly disabled by the user). ]=], full_name = 'termguicolors', redraw = { 'ui_option' }, diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index c71eb633e9..d625c22c76 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -148,7 +148,8 @@ static bool cursor_style_enabled = false; # include "tui/tui.c.generated.h" #endif -void tui_start(TUIData **tui_p, int *width, int *height, char **term) +void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb) + FUNC_ATTR_NONNULL_ALL { TUIData *tui = xcalloc(1, sizeof(TUIData)); tui->is_starting = true; @@ -177,6 +178,7 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term) *width = tui->width; *height = tui->height; *term = tui->term; + *rgb = tui->rgb; } void tui_set_key_encoding(TUIData *tui) @@ -334,6 +336,9 @@ static void terminfo_start(TUIData *tui) int konsolev = konsolev_env ? (int)strtol(konsolev_env, NULL, 10) : (konsole ? 1 : 0); + // truecolor support must be checked before patching/augmenting terminfo + tui->rgb = term_has_truecolor(tui, colorterm); + patch_terminfo_bugs(tui, term, colorterm, vtev, konsolev, iterm_env, nsterm); augment_terminfo(tui, term, vtev, konsolev, iterm_env, nsterm); tui->can_change_scroll_region = @@ -1439,7 +1444,7 @@ void tui_suspend(TUIData *tui) tui_mouse_on(tui); } stream_set_blocking(tui->input.in_fd, false); // libuv expects this - ui_client_attach(tui->width, tui->height, tui->term); + ui_client_attach(tui->width, tui->height, tui->term, tui->rgb); #endif } @@ -1752,6 +1757,44 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name) return -1; } +/// Determine if the terminal supports truecolor or not: +/// +/// 1. If $COLORTERM is "24bit" or "truecolor", return true +/// 2. Else, check terminfo for Tc, RGB, setrgbf, or setrgbb capabilities. If +/// found, return true +/// 3. Else, return false +static bool term_has_truecolor(TUIData *tui, const char *colorterm) +{ + // Check $COLORTERM + if (strequal(colorterm, "truecolor") || strequal(colorterm, "24bit")) { + return true; + } + + // Check for Tc and RGB + for (size_t i = 0; i < unibi_count_ext_bool(tui->ut); i++) { + const char *n = unibi_get_ext_bool_name(tui->ut, i); + if (n && (!strcmp(n, "Tc") || !strcmp(n, "RGB"))) { + return true; + } + } + + // Check for setrgbf and setrgbb + bool setrgbf = false; + bool setrgbb = false; + for (size_t i = 0; i < unibi_count_ext_str(tui->ut) && (!setrgbf || !setrgbb); i++) { + const char *n = unibi_get_ext_str_name(tui->ut, i); + if (n) { + if (!setrgbf && !strcmp(n, "setrgbf")) { + setrgbf = true; + } else if (!setrgbb && !strcmp(n, "setrgbb")) { + setrgbb = true; + } + } + } + + return setrgbf && setrgbb; +} + /// Patches the terminfo records after loading from system or built-in db. /// Several entries in terminfo are known to be deficient or outright wrong; /// and several terminal emulators falsely announce incorrect terminal types. diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index eb32c16881..d744560a86 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -70,14 +70,14 @@ uint64_t ui_client_start_server(int argc, char **argv) return channel->id; } -void ui_client_attach(int width, int height, char *term) +void ui_client_attach(int width, int height, char *term, bool rgb) { MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, INTEGER_OBJ(width)); ADD_C(args, INTEGER_OBJ(height)); MAXSIZE_TEMP_DICT(opts, 9); - PUT_C(opts, "rgb", BOOLEAN_OBJ(true)); + PUT_C(opts, "rgb", BOOLEAN_OBJ(rgb)); PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true)); PUT_C(opts, "ext_termcolors", BOOLEAN_OBJ(true)); if (term) { @@ -111,9 +111,10 @@ void ui_client_run(bool remote_ui) ui_client_is_remote = remote_ui; int width, height; char *term; - tui_start(&tui, &width, &height, &term); + bool rgb; + tui_start(&tui, &width, &height, &term, &rgb); - ui_client_attach(width, height, term); + ui_client_attach(width, height, term, rgb); // os_exit() will be invoked when the client channel detaches while (true) { -- cgit From 8f10362cdc5835a1cd86c8195ce8e3b10ab85384 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 4 Dec 2023 09:50:00 +0100 Subject: fix(startup): only send one default_colors_set event during startup If the color scheme is changed in a startup script, nvim used to send multiple default_colors_set events, one for the default color scheme and one for the user's chosen color scheme. This would cause flicker in some UI:s. Throttle this event until we actually start drawing on the screen. fixes #26372 --- src/nvim/ui.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ui.c b/src/nvim/ui.c index cb4ebb5c3b..a78a5b077f 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -63,6 +63,7 @@ bool ui_cb_ext[kUIExtCount]; ///< Internalized UI capabilities. static bool has_mouse = false; static int pending_has_mouse = -1; +static bool pending_default_colors = false; static Array call_buf = ARRAY_DICT_INIT; @@ -283,8 +284,21 @@ void ui_schedule_refresh(void) void ui_default_colors_set(void) { - ui_call_default_colors_set(normal_fg, normal_bg, normal_sp, - cterm_normal_fg_color, cterm_normal_bg_color); + // Throttle setting of default colors at startup, so it only happens once + // if the user sets the colorscheme in startup. + pending_default_colors = true; + if (starting == 0) { + ui_may_set_default_colors(); + } +} + +static void ui_may_set_default_colors(void) +{ + if (pending_default_colors) { + pending_default_colors = false; + ui_call_default_colors_set(normal_fg, normal_bg, normal_sp, + cterm_normal_fg_color, cterm_normal_bg_color); + } } void ui_busy_start(void) @@ -442,6 +456,9 @@ void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, flags |= kLineFlagInvalid; } + // set default colors now so that that text won't have to be repainted later + ui_may_set_default_colors(); + size_t off = grid->line_offset[row] + (size_t)startcol; ui_call_raw_line(grid->handle, row, startcol, endcol, clearcol, clearattr, -- cgit From 3198598e6974ae2009e816aeb96462cdfc3c59e9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Dec 2023 07:35:52 +0800 Subject: fix(tui): use uv_timer_t instead of TimeWatcher for input (#26435) Avoid scheduling on main loop. Fix #26425 --- src/nvim/tui/input.c | 24 ++++++++++++------------ src/nvim/tui/input.h | 3 +-- src/nvim/tui/tui.c | 3 +-- 3 files changed, 14 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index c533b288c1..6c47d1b5c7 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -156,14 +156,15 @@ void tinput_init(TermInput *input, Loop *loop) rstream_init_fd(loop, &input->read_stream, input->in_fd, READ_STREAM_SIZE); // initialize a timer handle for handling ESC with libtermkey - time_watcher_init(loop, &input->timer_handle, input); + uv_timer_init(&loop->uv, &input->timer_handle); + input->timer_handle.data = input; } void tinput_destroy(TermInput *input) { map_destroy(int, &kitty_key_map); rbuffer_free(input->key_buffer); - time_watcher_close(&input->timer_handle, NULL); + uv_close((uv_handle_t *)&input->timer_handle, NULL); stream_close(&input->read_stream, NULL, NULL); termkey_destroy(input->tk); } @@ -176,7 +177,7 @@ void tinput_start(TermInput *input) void tinput_stop(TermInput *input) { rstream_stop(&input->read_stream); - time_watcher_stop(&input->timer_handle); + uv_timer_stop(&input->timer_handle); } static void tinput_done_event(void **argv) @@ -466,17 +467,16 @@ static void tk_getkeys(TermInput *input, bool force) if (input->ttimeout && input->ttimeoutlen >= 0) { // Stop the current timer if already running - time_watcher_stop(&input->timer_handle); - time_watcher_start(&input->timer_handle, tinput_timer_cb, - (uint64_t)input->ttimeoutlen, 0); + uv_timer_stop(&input->timer_handle); + uv_timer_start(&input->timer_handle, tinput_timer_cb, (uint64_t)input->ttimeoutlen, 0); } else { tk_getkeys(input, true); } } -static void tinput_timer_cb(TimeWatcher *watcher, void *data) +static void tinput_timer_cb(uv_timer_t *handle) { - TermInput *input = (TermInput *)data; + TermInput *input = handle->data; // If the raw buffer is not empty, process the raw buffer first because it is // processing an incomplete bracketed paster sequence. if (rbuffer_size(input->read_stream.buffer)) { @@ -489,8 +489,8 @@ static void tinput_timer_cb(TimeWatcher *watcher, void *data) /// Handle focus events. /// /// If the upcoming sequence of bytes in the input stream matches the termcode -/// for "focus gained" or "focus lost", consume that sequence and schedule an -/// event on the main loop. +/// for "focus gained" or "focus lost", consume that sequence and send an event +/// to Nvim server. /// /// @param input the input stream /// @return true iff handle_focus_event consumed some input @@ -757,8 +757,8 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *da int64_t ms = input->ttimeout ? (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0; // Stop the current timer if already running - time_watcher_stop(&input->timer_handle); - time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0); + uv_timer_stop(&input->timer_handle); + uv_timer_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0); return; } diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index 9d276277de..bc490754be 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -6,7 +6,6 @@ #include "nvim/event/loop.h" #include "nvim/event/stream.h" -#include "nvim/event/time.h" #include "nvim/rbuffer_defs.h" #include "nvim/tui/input_defs.h" // IWYU pragma: export #include "nvim/tui/tui.h" @@ -33,7 +32,7 @@ typedef struct { OptInt ttimeoutlen; TermKey *tk; TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook - TimeWatcher timer_handle; + uv_timer_t timer_handle; Loop *loop; Stream read_stream; RBuffer *key_buffer; diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index d625c22c76..f500994229 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -170,8 +170,7 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb) uv_timer_init(&tui->loop->uv, &tui->startup_delay_timer); tui->startup_delay_timer.data = tui; - uv_timer_start(&tui->startup_delay_timer, after_startup_cb, - 100, 0); + uv_timer_start(&tui->startup_delay_timer, after_startup_cb, 100, 0); *tui_p = tui; loop_poll_events(&main_loop, 1); -- cgit From ec80e4cb4d3145a0ab6c3f2820c9f21f2108d5ab Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 6 Dec 2023 18:52:10 -0500 Subject: fix(log): increase size of buffer for nvim instance name 16 bytes is not enough room for existing usage of the buffer by the tests, so the name may get truncated and cause log_spec test to fail: FAILED test/functional/core/log_spec.lua @ 30: log messages are formatted with name or test id test/helpers.lua:146: retry() attempts: 51 test/helpers.lua:155: Pattern "%.%d+%.%d/c +server_init:%d+: test log message" not found in log (last 100 lines): Xtest_logging: ERR 2023-11-24T23:36:34.252 T1274.2445945.0 server_init:57: test log message ERR 2023-11-24T23:36:34.275 T1274.2445945.0 server_init:57: test log message --- src/nvim/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/log.c b/src/nvim/log.c index a93dab6238..4370693f49 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -295,7 +295,7 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context, FUNC_ATTR_PRINTF(7, 0) { // Name of the Nvim instance that produced the log. - static char name[16] = { 0 }; + static char name[32] = { 0 }; static const char *log_levels[] = { [LOGLVL_DBG] = "DBG", -- cgit From a4047e0b8063ddc8da11bb89d3aba9cf614dbaa8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 11:12:24 +0800 Subject: version.c: update (#26441) Co-authored-by: marvim --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index fc93a01b32..2caf2c0cb8 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -896,7 +896,7 @@ static const int included_patches[] = { // 1586, 1585, // 1584, - // 1583, + 1583, 1582, 1581, // 1580, -- cgit From 1dba570e63edcc69d6661bdcb9857def8bb18039 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Dec 2023 12:04:02 +0800 Subject: fix(inccommand): save and restore '[ and '] marks (#26442) Undoing a change moves '[ and '] marks, so it is necessary to save and restore them. --- src/nvim/ex_getln.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index f31f8fec55..14d230331a 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -152,6 +152,8 @@ typedef struct cmdpreview_buf_info { buf_T *buf; OptInt save_b_p_ul; int save_b_changed; + pos_T save_b_op_start; + pos_T save_b_op_end; varnumber_T save_changedtick; CpUndoInfo undo_info; } CpBufInfo; @@ -2360,6 +2362,8 @@ static void cmdpreview_prepare(CpInfo *cpinfo) cp_bufinfo.buf = buf; cp_bufinfo.save_b_p_ul = buf->b_p_ul; cp_bufinfo.save_b_changed = buf->b_changed; + cp_bufinfo.save_b_op_start = buf->b_op_start; + cp_bufinfo.save_b_op_end = buf->b_op_end; cp_bufinfo.save_changedtick = buf_get_changedtick(buf); cmdpreview_save_undo(&cp_bufinfo.undo_info, buf); kv_push(cpinfo->buf_info, cp_bufinfo); @@ -2438,6 +2442,9 @@ static void cmdpreview_restore_state(CpInfo *cpinfo) u_blockfree(buf); cmdpreview_restore_undo(&cp_bufinfo.undo_info, buf); + buf->b_op_start = cp_bufinfo.save_b_op_start; + buf->b_op_end = cp_bufinfo.save_b_op_end; + if (cp_bufinfo.save_changedtick != buf_get_changedtick(buf)) { buf_set_changedtick(buf, cp_bufinfo.save_changedtick); } -- cgit From bc5b0da84ec4d8ba01d17fc4e0f616fd3fe46f8e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Dec 2023 15:54:05 +0800 Subject: fix(inccommand): don't crash with "split" and 'n' flag --- src/nvim/ex_cmds.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 0711d82fe5..68c316fde0 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4580,7 +4580,6 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i } // Width of the "| lnum|..." column which displays the line numbers. - linenr_T highest_num_line = 0; int col_width = 0; // Use preview window only when inccommand=split and range is not just the current line bool preview = (*p_icm == 's') && (eap->line1 != old_cusr.lnum || eap->line2 != old_cusr.lnum); @@ -4590,8 +4589,11 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i assert(cmdpreview_buf != NULL); if (lines.subresults.size > 0) { - highest_num_line = kv_last(lines.subresults).end.lnum; - col_width = (int)log10(highest_num_line) + 1 + 3; + SubResult last_match = kv_last(lines.subresults); + // `last_match.end.lnum` may be 0 when using 'n' flag. + linenr_T highest_lnum = MAX(last_match.start.lnum, last_match.end.lnum); + assert(highest_lnum > 0); + col_width = (int)log10(highest_lnum) + 1 + 3; } } -- cgit From aba954b662cc1223d11ac3dc99323b9ebf687085 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Dec 2023 19:14:56 +0800 Subject: fix(terminal): never propagate $COLORTERM from outer env (#26440) If $COLORTERM is "truecolor" but the user sets 'notermguicolors', propagating $COLORTERM to :terminal usually doesn't work well. --- src/nvim/eval/funcs.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 0054c47678..4029478072 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3898,12 +3898,13 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_number = 1; } -static const char *ignored_env_vars[] = { +static const char *pty_ignored_env_vars[] = { #ifndef MSWIN "COLUMNS", "LINES", "TERMCAP", "COLORFGBG", + "COLORTERM", #endif NULL }; @@ -3943,9 +3944,9 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en // child process. We're removing them here so the user can still decide // they want to explicitly set them. for (size_t i = 0; - i < ARRAY_SIZE(ignored_env_vars) && ignored_env_vars[i]; + i < ARRAY_SIZE(pty_ignored_env_vars) && pty_ignored_env_vars[i]; i++) { - dictitem_T *dv = tv_dict_find(env, ignored_env_vars[i], -1); + dictitem_T *dv = tv_dict_find(env, pty_ignored_env_vars[i], -1); if (dv) { tv_dict_item_remove(env, dv); } @@ -3953,10 +3954,6 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en #ifndef MSWIN // Set COLORTERM to "truecolor" if termguicolors is set if (p_tgc) { - dictitem_T *dv = tv_dict_find(env, S_LEN("COLORTERM")); - if (dv) { - tv_dict_item_remove(env, dv); - } tv_dict_add_str(env, S_LEN("COLORTERM"), "truecolor"); } #endif -- cgit From cca6c4c6986abc67cd213ad1d32d329384a57790 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 6 Dec 2023 17:02:13 +0100 Subject: feat(rpc): allow empty string key in msgpack => Vim conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Since e057b38e7037 #20757 we support empty key in JSON encode/decode, but we don't allow it in RPC object => Vim dict conversion. But empty string is a valid key in Vim dicts and the msgpack spec. Empty string key was disallowed in 7c01d5ff9286 (2014) but that commit/PR doesn't explicitly discuss it, so presumably it was a "seems reasonable" decision (or Vimscript didn't allow empty keys until later). Solution: Remove the check in `object_to_vim()`. Note that `tv_dict_item_alloc_len` will invoke `memcpy(…, 0)` but that's allowed by the C spec: https://stackoverflow.com/a/3751937/152142 --- src/nvim/api/private/converter.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c index ef57bde32d..1e11683c38 100644 --- a/src/nvim/api/private/converter.c +++ b/src/nvim/api/private/converter.c @@ -328,15 +328,6 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) for (uint32_t i = 0; i < obj.data.dictionary.size; i++) { KeyValuePair item = obj.data.dictionary.items[i]; String key = item.key; - - if (key.size == 0) { - api_set_error(err, kErrorTypeValidation, - "Empty dictionary keys aren't allowed"); - // cleanup - tv_dict_free(dict); - return false; - } - dictitem_T *const di = tv_dict_item_alloc(key.data); if (!object_to_vim(item.value, &di->di_tv, err)) { -- cgit From a16218d4c6773c474011149661470af6e8c90892 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 7 Dec 2023 13:01:42 +0100 Subject: refactor: object_to_vim() cannot fail Since the parent commit, object_to_vim() can't fail, so callers don't need to check its result. --- src/nvim/api/private/converter.c | 22 +++------------------- src/nvim/api/private/helpers.c | 4 +--- src/nvim/api/vimscript.c | 9 ++------- src/nvim/channel.c | 4 ++-- src/nvim/context.c | 4 +--- src/nvim/eval/funcs.c | 14 ++++---------- src/nvim/mapping.c | 4 ++-- 7 files changed, 15 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c index 1e11683c38..e7b8934c97 100644 --- a/src/nvim/api/private/converter.c +++ b/src/nvim/api/private/converter.c @@ -258,9 +258,7 @@ Object vim_to_object(typval_T *obj) /// @param tv Conversion result is placed here. On failure member v_type is /// set to VAR_UNKNOWN (no allocation was made for this variable). /// @param err Error object. -/// -/// @returns true if conversion is successful, otherwise false. -bool object_to_vim(Object obj, typval_T *tv, Error *err) +void object_to_vim(Object obj, typval_T *tv, Error *err) { tv->v_type = VAR_UNKNOWN; tv->v_lock = VAR_UNLOCKED; @@ -307,12 +305,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) for (uint32_t i = 0; i < obj.data.array.size; i++) { Object item = obj.data.array.items[i]; typval_T li_tv; - - if (!object_to_vim(item, &li_tv, err)) { - tv_list_free(list); - return false; - } - + object_to_vim(item, &li_tv, err); tv_list_append_owned_tv(list, li_tv); } tv_list_ref(list); @@ -329,14 +322,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) KeyValuePair item = obj.data.dictionary.items[i]; String key = item.key; dictitem_T *const di = tv_dict_item_alloc(key.data); - - if (!object_to_vim(item.value, &di->di_tv, err)) { - // cleanup - tv_dict_item_free(di); - tv_dict_free(dict); - return false; - } - + object_to_vim(item.value, &di->di_tv, err); tv_dict_add(dict, di); } dict->dv_refcount++; @@ -353,6 +339,4 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) break; } } - - return true; } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index b23684aee9..2772fa8b59 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -253,9 +253,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva typval_T tv; // Convert the object to a vimscript type in the temporary variable - if (!object_to_vim(value, &tv, err)) { - return rv; - } + object_to_vim(value, &tv, err); typval_T oldtv = TV_INITIAL_VALUE; diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 25a34f769c..3bca988030 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -207,9 +207,7 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) typval_T vim_args[MAX_FUNC_ARGS + 1]; size_t i = 0; // also used for freeing the variables for (; i < args.size; i++) { - if (!object_to_vim(args.items[i], &vim_args[i], err)) { - goto free_vim_args; - } + object_to_vim(args.items[i], &vim_args[i], err); } // Initialize `force_abort` and `suppress_errthrow` at the top level. @@ -243,7 +241,6 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) tv_clear(&rettv); recursive--; -free_vim_args: while (i > 0) { tv_clear(&vim_args[--i]); } @@ -297,9 +294,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err) mustfree = true; break; case kObjectTypeDictionary: - if (!object_to_vim(dict, &rettv, err)) { - goto end; - } + object_to_vim(dict, &rettv, err); break; default: api_set_error(err, kErrorTypeValidation, diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 767c8d29b8..ca8cbed8f9 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -233,7 +233,7 @@ void channel_create_event(Channel *chan, const char *ext_source) typval_T tv = TV_INITIAL_VALUE; // TODO(bfredl): do the conversion in one step. Also would be nice // to pretty print top level dict in defined order - (void)object_to_vim(DICTIONARY_OBJ(info), &tv, NULL); + object_to_vim(DICTIONARY_OBJ(info), &tv, NULL); assert(tv.v_type == VAR_DICT); char *str = encode_tv2json(&tv, NULL); ILOG("new channel %" PRIu64 " (%s) : %s", chan->id, source, str); @@ -865,7 +865,7 @@ static void set_info_event(void **argv) dict_T *dict = get_v_event(&save_v_event); Dictionary info = channel_info(chan->id); typval_T retval; - (void)object_to_vim(DICTIONARY_OBJ(info), &retval, NULL); + object_to_vim(DICTIONARY_OBJ(info), &retval, NULL); assert(retval.v_type == VAR_DICT); tv_dict_add_dict(dict, S_LEN("info"), retval.vval.v_dict); tv_dict_set_keys_readonly(dict); diff --git a/src/nvim/context.c b/src/nvim/context.c index 5f47cfc225..28a67061c6 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -326,9 +326,7 @@ static inline msgpack_sbuffer array_to_sbuf(Array array, Error *err) msgpack_sbuffer_init(&sbuf); typval_T list_tv; - if (!object_to_vim(ARRAY_OBJ(array), &list_tv, err)) { - return sbuf; - } + object_to_vim(ARRAY_OBJ(array), &list_tv, err); assert(list_tv.v_type == VAR_LIST); if (!encode_vim_list_to_buf(list_tv.vval.v_list, &sbuf.size, &sbuf.data)) { diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4029478072..c1c865df60 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -355,10 +355,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) goto end; } - if (!object_to_vim(result, rettv, &err)) { - assert(ERROR_SET(&err)); - semsg(_("Error converting the call result: %s"), err.msg); - } + object_to_vim(result, rettv, &err); end: api_free_array(args); @@ -428,7 +425,7 @@ static void f_and(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) static void f_api_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { Dictionary metadata = api_metadata(); - (void)object_to_vim(DICTIONARY_OBJ(metadata), rettv, NULL); + object_to_vim(DICTIONARY_OBJ(metadata), rettv, NULL); } /// "atan2()" function @@ -1023,7 +1020,7 @@ static void f_ctxget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) Dictionary ctx_dict = ctx_to_dict(ctx); Error err = ERROR_INIT; - (void)object_to_vim(DICTIONARY_OBJ(ctx_dict), rettv, &err); + object_to_vim(DICTIONARY_OBJ(ctx_dict), rettv, &err); api_free_dictionary(ctx_dict); api_clear_error(&err); } @@ -6751,10 +6748,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) goto end; } - if (!object_to_vim(result, rettv, &err)) { - assert(ERROR_SET(&err)); - semsg(_("Error converting the call result: %s"), err.msg); - } + object_to_vim(result, rettv, &err); end: arena_mem_free(res_mem); diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 56544a9956..345ec45152 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -2199,7 +2199,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) Dictionary dict = mapblock_fill_dict(mp, did_simplify ? keys_simplified : NULL, buffer_local, abbr, true); - (void)object_to_vim(DICTIONARY_OBJ(dict), rettv, NULL); + object_to_vim(DICTIONARY_OBJ(dict), rettv, NULL); api_free_dictionary(dict); } else { // Return an empty dictionary. @@ -2407,7 +2407,7 @@ void f_maplist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) did_simplify ? keys_buf : NULL, buffer_local, abbr, true); typval_T d = TV_INITIAL_VALUE; - (void)object_to_vim(DICTIONARY_OBJ(dict), &d, NULL); + object_to_vim(DICTIONARY_OBJ(dict), &d, NULL); assert(d.v_type == VAR_DICT); tv_list_append_dict(rettv->vval.v_list, d.vval.v_dict); api_free_dictionary(dict); -- cgit From 4a34da82c18e6da1e46d6bf3d21082a6b6c8b947 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Wed, 6 Dec 2023 13:34:19 +0100 Subject: perf(column): keep track of number of lines that hold up the 'signcolumn' Problem: The entire marktree needs to be traversed each time a sign is removed from the sentinel line. Solution: Remove sentinel line and instead keep track of the number of lines that hold up the 'signcolumn' in "max_count". Adjust this number for added/removed signs, and set it to 0 when the maximum number of signs on a line changes. Only when "max_count" is decremented to 0 due to sign removal do we need to check the entire buffer. Also replace "invalid_top" and "invalid_bot" with a map of invalid ranges, further reducing the number of lines to be checked. Also improve tree traversal when counting the number of signs. Instead of looping over the to be checked range and counting the overlap for each row, keep track of the overlap in an array and add this to the count. --- src/nvim/api/vim.c | 1 - src/nvim/buffer.c | 66 ++------------------ src/nvim/buffer_defs.h | 9 ++- src/nvim/decoration.c | 164 ++++++++++++++++++++++++++++++++++++------------- src/nvim/drawscreen.c | 54 +++++++++------- src/nvim/extmark.c | 20 +----- src/nvim/map.c | 3 + src/nvim/map_defs.h | 3 + src/nvim/move.c | 2 +- src/nvim/option.c | 14 ----- src/nvim/optionstr.c | 2 + src/nvim/textformat.c | 2 +- src/nvim/types_defs.h | 7 +++ 13 files changed, 182 insertions(+), 165 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0842469c59..2c937113e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2189,7 +2189,6 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int cul_id = 0; int num_id = 0; linenr_T lnum = statuscol_lnum; - wp->w_scwidth = win_signcol_count(wp); decor_redraw_signs(wp, wp->w_buffer, lnum - 1, sattrs, &line_id, &cul_id, &num_id); statuscol.sattrs = sattrs; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8a594dea92..b5fac15af6 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -750,6 +750,8 @@ void buf_clear(void) { linenr_T line_count = curbuf->b_ml.ml_line_count; extmark_free_all(curbuf); // delete any extmarks + map_destroy(int, curbuf->b_signcols.invalid); + *curbuf->b_signcols.invalid = (Map(int, SignRange)) MAP_INIT; while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) { ml_delete(1, false); } @@ -920,6 +922,8 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) } uc_clear(&buf->b_ucmds); // clear local user commands extmark_free_all(buf); // delete any extmarks + map_destroy(int, buf->b_signcols.invalid); + *buf->b_signcols.invalid = (Map(int, SignRange)) MAP_INIT; map_clear_mode(buf, MAP_ALL_MODES, true, false); // clear local mappings map_clear_mode(buf, MAP_ALL_MODES, true, true); // clear local abbrevs XFREE_CLEAR(buf->b_start_fenc); @@ -1844,7 +1848,6 @@ buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags) buf = xcalloc(1, sizeof(buf_T)); // init b: variables buf->b_vars = tv_dict_alloc(); - buf->b_signcols.sentinel = 0; init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE); buf_init_changedtick(buf); } @@ -4026,67 +4029,6 @@ char *buf_spname(buf_T *buf) return NULL; } -/// Invalidate the signcolumn if needed after deleting a sign ranging from line1 to line2. -void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2) -{ - linenr_T sent = buf->b_signcols.sentinel; - if (sent >= line1 && sent <= line2) { - // When removed sign overlaps the sentinel line, entire buffer needs to be checked. - buf->b_signcols.sentinel = buf->b_signcols.size = 0; - } -} - -/// Invalidate the signcolumn if needed after adding a sign ranging from line1 to line2. -void buf_signcols_add_check(buf_T *buf, linenr_T line1, linenr_T line2) -{ - if (!buf->b_signcols.sentinel) { - return; - } - - linenr_T sent = buf->b_signcols.sentinel; - if (sent >= line1 && sent <= line2) { - // If added sign overlaps sentinel line, increment without invalidating. - if (buf->b_signcols.size == buf->b_signcols.max) { - buf->b_signcols.max++; - } - buf->b_signcols.size++; - return; - } - - if (line1 < buf->b_signcols.invalid_top) { - buf->b_signcols.invalid_top = line1; - } - if (line2 > buf->b_signcols.invalid_bot) { - buf->b_signcols.invalid_bot = line2; - } -} - -int buf_signcols(buf_T *buf, int max) -{ - if (!buf->b_signs_with_text) { - buf->b_signcols.size = 0; - } else if (max <= 1 && buf->b_signs_with_text >= (size_t)max) { - buf->b_signcols.size = max; - } else { - linenr_T sent = buf->b_signcols.sentinel; - if (!sent || max > buf->b_signcols.max) { - // Recheck if the window scoped maximum 'signcolumn' is greater than the - // previous maximum or if there is no sentinel line yet. - buf->b_signcols.invalid_top = sent ? sent : 1; - buf->b_signcols.invalid_bot = sent ? sent : buf->b_ml.ml_line_count; - } - - if (buf->b_signcols.invalid_bot) { - decor_validate_signcols(buf, max); - } - } - - buf->b_signcols.max = max; - buf->b_signcols.invalid_top = MAXLNUM; - buf->b_signcols.invalid_bot = 0; - return buf->b_signcols.size; -} - /// Get "buf->b_fname", use "[No Name]" if it is NULL. char *buf_get_fname(const buf_T *buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 7402e66403..beb3ec95b8 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -703,11 +703,10 @@ struct file_buffer { // may use a different synblock_T. struct { - int size; // last calculated number of sign columns - int max; // maximum value size is valid for. - linenr_T sentinel; // a line number which is holding up the signcolumn - linenr_T invalid_top; // first invalid line number that needs to be checked - linenr_T invalid_bot; // last invalid line number that needs to be checked + int max; // maximum number of signs on a single line + int max_count; // number of lines with max number of signs + bool resized; // whether max changed at start of redraw + Map(int, SignRange) invalid[1]; // map of invalid ranges to be checked } b_signcols; Terminal *terminal; // Terminal instance associated with the buffer diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index ccba8bd607..20311d80e5 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -203,21 +203,21 @@ void buf_put_decor_virt(buf_T *buf, DecorVirtText *vt) } static int sign_add_id = 0; -void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row, int row2) +void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2) { if (sh->flags & kSHIsSign) { sh->sign_add_id = sign_add_id++; buf->b_signs++; if (sh->text.ptr) { buf->b_signs_with_text++; - buf_signcols_add_check(buf, row + 1, row2 + 1); + buf_signcols_invalidate_range(buf, row1, row2, 1); } } } -void buf_decor_remove(buf_T *buf, int row, int row2, DecorInline decor, bool free) +void buf_decor_remove(buf_T *buf, int row1, int row2, DecorInline decor, bool free) { - decor_redraw(buf, row, row2, decor); + decor_redraw(buf, row1, row2, decor); if (decor.ext) { DecorVirtText *vt = decor.data.ext.vt; while (vt) { @@ -227,7 +227,7 @@ void buf_decor_remove(buf_T *buf, int row, int row2, DecorInline decor, bool fre uint32_t idx = decor.data.ext.sh_idx; while (idx != DECOR_ID_INVALID) { DecorSignHighlight *sh = &kv_A(decor_items, idx); - buf_remove_decor_sh(buf, row, row2, sh); + buf_remove_decor_sh(buf, row1, row2, sh); idx = sh->next; } if (free) { @@ -249,7 +249,7 @@ void buf_remove_decor_virt(buf_T *buf, DecorVirtText *vt) } } -void buf_remove_decor_sh(buf_T *buf, int row, int row2, DecorSignHighlight *sh) +void buf_remove_decor_sh(buf_T *buf, int row1, int row2, DecorSignHighlight *sh) { if (sh->flags & kSHIsSign) { assert(buf->b_signs > 0); @@ -257,8 +257,8 @@ void buf_remove_decor_sh(buf_T *buf, int row, int row2, DecorSignHighlight *sh) if (sh->text.ptr) { assert(buf->b_signs_with_text > 0); buf->b_signs_with_text--; - if (row2 >= row) { - buf_signcols_del_check(buf, row + 1, row2 + 1); + if (row2 >= row1) { + buf_signcols_invalidate_range(buf, row1, row2, -1); } } } @@ -792,50 +792,128 @@ DecorSignHighlight *decor_find_sign(DecorInline decor) } } -// Increase the signcolumn size and update the sentinel line if necessary for -// the invalidated range. -void decor_validate_signcols(buf_T *buf, int max) +/// If "count" is greater than current max, set it and reset "max_count". +static void buf_signcols_validate_row(buf_T *buf, int count, int add) { - int signcols = 0; // highest value of count - int currow = buf->b_signcols.invalid_top - 1; - // TODO(bfredl): only need to use marktree_itr_get_overlap once. - // then we can process both start and end events and update state for each row - for (; currow < buf->b_signcols.invalid_bot; currow++) { - MarkTreeIter itr[1]; - if (!marktree_itr_get_overlap(buf->b_marktree, currow, 0, itr)) { - continue; - } + int del = add < 0 ? -add : 0; + if (count > buf->b_signcols.max) { + buf->b_signcols.max = count; + buf->b_signcols.max_count = 0; + buf->b_signcols.resized = true; + } + /// Add sign of "add" to "max_count" + if (count == buf->b_signcols.max - del) { + buf->b_signcols.max_count += (add > 0) - (add < 0); + } +} - int count = 0; - MTPair pair; - while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) { - if (!mt_invalid(pair.start) && (pair.start.flags & MT_FLAG_DECOR_SIGNTEXT)) { - count++; - } +/// Validate a range by counting the number of overlapping signs and adjusting +/// "b_signcols" accordingly. +static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) +{ + int count = 0; // Number of signs on the current line + int currow = row1; + MTPair pair = { 0 }; + MarkTreeIter itr[1]; + + // Allocate an array of integers holding the overlapping signs in the range. + assert(row2 >= row1); + int *overlap = xcalloc(sizeof(int), (size_t)(row2 + 1 - row1)); + + // First find the number of overlapping signs at "row1". + marktree_itr_get_overlap(buf->b_marktree, currow, 0, itr); + while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) { + if (!mt_invalid(pair.start) && pair.start.flags & MT_FLAG_DECOR_SIGNTEXT) { + overlap[0]++; } + } - while (itr->x) { - MTKey mark = marktree_itr_current(itr); - if (mark.pos.row != currow) { - break; - } - if (!mt_invalid(mark) && !mt_end(mark) && (mark.flags & MT_FLAG_DECOR_SIGNTEXT)) { - count++; - } - marktree_itr_next(buf->b_marktree, itr); + // Continue traversing the marktree until beyond "row2". Increment "count" for + // the start of a mark, increment the overlap array until the end of a paired mark. + while (itr->x) { + MTKey mark = marktree_itr_current(itr); + if (mark.pos.row > row2) { + break; + } + // Finish the count at the previous row. + if (mark.pos.row != currow) { + buf_signcols_validate_row(buf, count + overlap[currow - row1], add); + currow = mark.pos.row; + count = 0; } - if (count > signcols) { - if (count >= buf->b_signcols.size) { - buf->b_signcols.size = count; - buf->b_signcols.sentinel = currow + 1; - } - if (count >= max) { - return; + // Increment count and overlap array for the range of a paired sign mark. + if (!mt_invalid(mark) && !mt_end(mark) && (mark.flags & MT_FLAG_DECOR_SIGNTEXT)) { + count++; + if (mt_paired(mark)) { + MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL); + for (int i = mark.pos.row; i < MIN(row2, end.row); i++) { + overlap[row2 - i]++; + } } - signcols = count; } + + marktree_itr_next(buf->b_marktree, itr); + } + buf_signcols_validate_row(buf, count + overlap[currow - row1], add); + xfree(overlap); +} + +int buf_signcols_validate(win_T *wp, buf_T *buf, bool stc_check) +{ + int start; + SignRange range; + map_foreach(buf->b_signcols.invalid, start, range, { + // Leave rest of the ranges invalid if max is already greater than + // configured maximum or resize is detected for 'statuscolumn' rebuild. + if ((!stc_check || buf->b_signcols.resized) + && (range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) { + return wp->w_maxscwidth; + } + buf_signcols_validate_range(buf, start, range.end, range.add); + }); + + // Check if we need to scan the entire buffer. + if (buf->b_signcols.max_count == 0) { + buf->b_signcols.max = 0; + buf->b_signcols.resized = true; + buf_signcols_validate_range(buf, 0, buf->b_ml.ml_line_count, 0); + } + + map_clear(int, buf->b_signcols.invalid); + return buf->b_signcols.max; +} + +static void buf_signcols_invalidate_range(buf_T *buf, int row1, int row2, int add) +{ + if (!buf->b_signs_with_text) { + buf->b_signcols.max = buf->b_signcols.max_count = 0; + buf->b_signcols.resized = true; + map_clear(int, buf->b_signcols.invalid); + return; + } + + // Remove an invalid range if sum of added/removed signs is now 0. + SignRange *srp = map_ref(int, SignRange)(buf->b_signcols.invalid, row1, NULL); + if (srp && srp->end == row2 && srp->add + add == 0) { + map_del(int, SignRange)(buf->b_signcols.invalid, row1, NULL); + return; } + + // Merge with overlapping invalid range. + int start; + SignRange range; + map_foreach(buf->b_signcols.invalid, start, range, { + if (row1 <= range.end && start <= row2) { + row1 = MIN(row1, start); + row2 = MAX(row2, range.end); + break; + } + }); + + srp = map_put_ref(int, SignRange)(buf->b_signcols.invalid, row1, NULL, NULL); + srp->end = row2; + srp->add += add; } void decor_redraw_end(DecorState *state) diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 85f62db774..a436dd2766 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -603,15 +603,6 @@ int update_screen(void) buf->b_mod_tick_decor = display_tick; } } - - // Reset 'statuscolumn' if there is no dedicated signcolumn but it is invalid. - if (*wp->w_p_stc != NUL && wp->w_minscwidth <= SCL_NO - && (wp->w_buffer->b_signcols.invalid_bot || !wp->w_buffer->b_signcols.sentinel)) { - wp->w_nrwidth_line_count = 0; - wp->w_valid &= ~VALID_WCOL; - wp->w_redr_type = UPD_NOT_VALID; - wp->w_buffer->b_signcols.invalid_bot = 0; - } } // Go from top to bottom through the windows, redrawing the ones that need it. @@ -658,10 +649,11 @@ int update_screen(void) win_check_ns_hl(NULL); - // Reset b_mod_set flags. Going through all windows is probably faster - // than going through all buffers (there could be many buffers). + // Reset b_mod_set and b_signcols.resized flags. Going through all windows is + // probably faster than going through all buffers (there could be many buffers). FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { wp->w_buffer->b_mod_set = false; + wp->w_buffer->b_signcols.resized = false; } updating_screen = 0; @@ -1200,17 +1192,33 @@ void comp_col(void) set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); } -static void redraw_win_signcol(win_T *wp) +/// Redraw entire window "wp" if configured 'signcolumn' width changes. +static bool win_redraw_signcols(win_T *wp) { - // If we can compute a change in the automatic sizing of the sign column - // under 'signcolumn=auto:X' and signs currently placed in the buffer, better - // figuring it out here so we can redraw the entire screen for it. - int scwidth = wp->w_scwidth; - wp->w_scwidth = win_signcol_count(wp); - if (wp->w_scwidth != scwidth) { - changed_line_abv_curs_win(wp); - redraw_later(wp, UPD_NOT_VALID); + bool rebuild_stc = false; + buf_T *buf = wp->w_buffer; + int width = buf->b_signcols.max; + + if (wp->w_minscwidth <= SCL_NO) { + if (*wp->w_p_stc) { + if (map_size(buf->b_signcols.invalid)) { + buf_signcols_validate(wp, buf, true); + } + if (buf->b_signcols.resized) { + rebuild_stc = true; + wp->w_nrwidth_line_count = 0; + } + } + width = 0; + } else if (wp->w_maxscwidth <= 1 && buf->b_signs_with_text >= (size_t)wp->w_maxscwidth) { + width = wp->w_maxscwidth; + } else if (map_size(buf->b_signcols.invalid)) { + width = buf_signcols_validate(wp, buf, false); } + + int scwidth = wp->w_scwidth; + wp->w_scwidth = MAX(wp->w_minscwidth, width); + return (wp->w_scwidth != scwidth || rebuild_stc); } /// Check if horizontal separator of window "wp" at specified window corner is connected to the @@ -1490,7 +1498,11 @@ static void win_update(win_T *wp, DecorProviders *providers) DecorProviders line_providers; decor_providers_invoke_win(wp, providers, &line_providers); - redraw_win_signcol(wp); + if (win_redraw_signcols(wp)) { + wp->w_lines_valid = 0; + wp->w_redr_type = UPD_NOT_VALID; + changed_line_abv_curs_win(wp); + } init_search_hl(wp, &screen_search_hl); diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 0b8aea35c0..92fbc6fb79 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -67,18 +67,18 @@ void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col } else { assert(marktree_itr_valid(itr)); if (old_mark.pos.row == row && old_mark.pos.col == col) { + // not paired: we can revise in place if (mt_decor_any(old_mark)) { + mt_itr_rawkey(itr).flags &= (uint16_t) ~MT_FLAG_DECOR_SIGNTEXT; buf_decor_remove(buf, row, row, mt_decor(old_mark), true); } - - // not paired: we can revise in place mt_itr_rawkey(itr).flags &= (uint16_t) ~MT_FLAG_EXTERNAL_MASK; mt_itr_rawkey(itr).flags |= flags; mt_itr_rawkey(itr).decor_data = decor.data; goto revised; } - buf_decor_remove(buf, old_mark.pos.row, old_mark.pos.row, mt_decor(old_mark), true); marktree_del_itr(buf->b_marktree, itr, false); + buf_decor_remove(buf, old_mark.pos.row, old_mark.pos.row, mt_decor(old_mark), true); } } else { *ns = MAX(*ns, id); @@ -515,20 +515,6 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t extmark_splice_delete(buf, start_row, start_col, end_row, end_col, uvp, false, undo); } - // Move the signcolumn sentinel line - if (buf->b_signs_with_text && buf->b_signcols.sentinel) { - linenr_T se_lnum = buf->b_signcols.sentinel; - if (se_lnum >= start_row) { - if (old_row != 0 && se_lnum > old_row + start_row) { - buf->b_signcols.sentinel += new_row - old_row; - } else if (new_row == 0) { - buf->b_signcols.sentinel = 0; - } else { - buf->b_signcols.sentinel += new_row; - } - } - } - marktree_splice(buf->b_marktree, (int32_t)start_row, start_col, old_row, old_col, new_row, new_col); diff --git a/src/nvim/map.c b/src/nvim/map.c index be6bf58daa..0011c97f9b 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -111,6 +111,9 @@ void mh_clear(MapHash *h) #define VAL_NAME(x) quasiquote(x, String) #include "nvim/map_value_impl.c.h" #undef VAL_NAME +#define VAL_NAME(x) quasiquote(x, SignRange) +#include "nvim/map_value_impl.c.h" +#undef VAL_NAME #undef KEY_NAME #define KEY_NAME(x) x##ptr_t diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h index f3c4e4ea95..b85ba5acaf 100644 --- a/src/nvim/map_defs.h +++ b/src/nvim/map_defs.h @@ -48,6 +48,7 @@ static const uint64_t value_init_uint64_t = 0; static const int64_t value_init_int64_t = 0; static const String value_init_String = STRING_INIT; static const ColorItem value_init_ColorItem = COLOR_ITEM_INITIALIZER; +static const SignRange value_init_SignRange = SIGNRANGE_INIT; // layer 0: type non-specific code @@ -150,6 +151,7 @@ KEY_DECLS(uint32_t) KEY_DECLS(String) KEY_DECLS(HlEntry) KEY_DECLS(ColorKey) +KEY_DECLS(SignRange) MAP_DECLS(int, int) MAP_DECLS(int, ptr_t) @@ -166,6 +168,7 @@ MAP_DECLS(uint32_t, uint32_t) MAP_DECLS(String, int) MAP_DECLS(int, String) MAP_DECLS(ColorKey, ColorItem) +MAP_DECLS(int, SignRange) #define set_has(T, set, key) set_has_##T(set, key) #define set_put(T, set, key) set_put_##T(set, key, NULL) diff --git a/src/nvim/move.c b/src/nvim/move.c index 227d064a27..12fb7d1f82 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -760,7 +760,7 @@ int win_col_off(win_T *wp) return ((wp->w_p_nu || wp->w_p_rnu || *wp->w_p_stc != NUL) ? (number_width(wp) + (*wp->w_p_stc == NUL)) : 0) + ((cmdwin_type == 0 || wp != curwin) ? 0 : 1) - + win_fdccol_count(wp) + (win_signcol_count(wp) * SIGN_WIDTH); + + win_fdccol_count(wp) + (wp->w_scwidth * SIGN_WIDTH); } int curwin_col_off(void) diff --git a/src/nvim/option.c b/src/nvim/option.c index ba9d1262d4..c9d65c5683 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -6172,20 +6172,6 @@ bool fish_like_shell(void) return strstr(path_tail(p_sh), "fish") != NULL; } -/// Return the number of requested sign columns, based on current -/// buffer signs and on user configuration. -int win_signcol_count(win_T *wp) -{ - if (wp->w_minscwidth <= SCL_NO) { - return 0; - } - - int needed_signcols = buf_signcols(wp->w_buffer, wp->w_maxscwidth); - int ret = MAX(wp->w_minscwidth, MIN(wp->w_maxscwidth, needed_signcols)); - assert(ret <= SIGN_SHOW_MAX); - return ret; -} - /// Get window or buffer local options dict_T *get_winbuf_options(const int bufopt) FUNC_ATTR_WARN_UNUSED_RESULT diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 544524dd42..64145ba6ac 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -2095,6 +2095,8 @@ const char *did_set_signcolumn(optset_T *args) if (check_signcolumn(win) != OK) { return e_invarg; } + int scwidth = win->w_minscwidth <= 0 ? 0 : MIN(win->w_maxscwidth, win->w_scwidth); + win->w_scwidth = MAX(win->w_minscwidth, scwidth); // When changing the 'signcolumn' to or from 'number', recompute the // width of the number column if 'number' or 'relativenumber' is set. if ((*oldval == 'n' && *(oldval + 1) == 'u') || win->w_minscwidth == SCL_NUM) { diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 7219e04add..5d7f5b747b 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -761,7 +761,7 @@ int comp_textwidth(bool ff) textwidth -= 1; } textwidth -= win_fdccol_count(curwin); - textwidth -= win_signcol_count(curwin); + textwidth -= curwin->w_scwidth; if (curwin->w_p_nu || curwin->w_p_rnu) { textwidth -= 8; diff --git a/src/nvim/types_defs.h b/src/nvim/types_defs.h index c06737abb5..27227685fa 100644 --- a/src/nvim/types_defs.h +++ b/src/nvim/types_defs.h @@ -48,3 +48,10 @@ typedef enum { #define TRISTATE_FROM_INT(val) ((val) == 0 ? kFalse : ((val) >= 1 ? kTrue : kNone)) typedef int64_t OptInt; + +// Range entry for the "b_signcols.invalid" map in which the keys are the range start. +typedef struct { + int end; // End of the invalid range. + int add; // Number of signs added in the invalid range, negative for deleted signs. +} SignRange; +#define SIGNRANGE_INIT { 0, 0 } -- cgit From b2d471ab337e56f660eb7c89ae24f447f7b7a165 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Thu, 7 Dec 2023 08:01:27 -0800 Subject: fix(lua): allow nil values in serialized Lua arrays (#26329) When we convert a Lua table to an Object, we consider the table a "dictionary" if it contains only string keys, and an array if it contains all numeric indices with no gaps. While rare, Lua tables can have both strictly numeric indices and gaps (e.g. { [2] = 2 }). These currently cannot be serialized because it is not considered an array. However, we know the maximum index of the table and as long as all of the keys in the table are numeric, it is still possible to serialize this table as an array. The missing indices will have nil values. --- src/nvim/lua/converter.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index fd2bdbd677..ca0be28fac 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -148,7 +148,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) } } else { if (tsize == 0 - || (tsize == ret.maxidx + || (tsize <= ret.maxidx && other_keys_num == 0 && ret.string_keys_num == 0)) { ret.type = kObjectTypeArray; @@ -1129,10 +1129,6 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) } const size_t idx = cur.obj->data.array.size++; lua_rawgeti(lstate, -1, (int)idx + 1); - if (lua_isnil(lstate, -1)) { - lua_pop(lstate, 2); - continue; - } kvi_push(stack, cur); cur = (ObjPopStackItem) { .obj = &cur.obj->data.array.items[idx], -- cgit From 5e78fd7784509dbbe146748e9264e5129cf68ab8 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 7 Dec 2023 07:58:03 -0800 Subject: fix(terminal): ignore $VIM and $VIMRUNTIME in pty jobs --- src/nvim/eval/funcs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index c1c865df60..15b81f2f56 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3903,6 +3903,8 @@ static const char *pty_ignored_env_vars[] = { "COLORFGBG", "COLORTERM", #endif + "VIM", + "VIMRUNTIME", NULL }; -- cgit From 9ae7d36ff5ebaf75597b442e10890bd77df01fbe Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 7 Dec 2023 00:40:48 +0600 Subject: refactor(options): split `get_option_value()` into smaller functions Problem: Currently, `get_option_value()` returns 3 separate things: The actual value of the option, whether the option is hidden, and the option flags. This makes the function difficult to refactor, modify or otherwise reason about. Solution: Split `get_option_value()` into 3 functions, each with a single purpose. This also affects `get_option_value_for()`. --- src/nvim/api/options.c | 43 +++++++++---------- src/nvim/context.c | 2 +- src/nvim/eval.c | 43 +++++++++---------- src/nvim/eval/vars.c | 11 +++-- src/nvim/option.c | 114 ++++++++++++++++++++----------------------------- src/nvim/spell.c | 2 +- 6 files changed, 94 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index ef7c11131a..53fd8af8b5 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -152,23 +152,20 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(9) { - Object rv = OBJECT_INIT; - OptVal value = NIL_OPTVAL; - int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; char *filetype = NULL; if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, &filetype, err)) { - goto err; + return (Object)OBJECT_INIT; } aco_save_T aco; buf_T *ftbuf = do_ft_buf(filetype, &aco, err); if (ERROR_SET(err)) { - goto err; + return (Object)OBJECT_INIT; } if (ftbuf != NULL) { @@ -176,8 +173,9 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) from = ftbuf; } - bool hidden; - value = get_option_value_for(name.data, NULL, scope, &hidden, req_scope, from, err); + int opt_idx = findoption(name.data); + OptVal value = get_option_value_for(opt_idx, scope, req_scope, from, err); + bool hidden = is_option_hidden(opt_idx); if (ftbuf != NULL) { // restore curwin/curbuf and a few other things @@ -198,7 +196,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) return optval_as_object(value); err: optval_free(value); - return rv; + return (Object)OBJECT_INIT; } /// Sets the value of an option. The behavior of this function matches that of @@ -391,6 +389,10 @@ static void restore_option_context(void *const ctx, OptReqScope req_scope) /// See SOPT_* in option_defs.h for other flags. int get_option_attrs(char *name) { + if (is_tty_option(name)) { + return SOPT_GLOBAL; + } + int opt_idx = findoption(name); if (opt_idx < 0) { @@ -399,10 +401,6 @@ int get_option_attrs(char *name) vimoption_T *opt = get_option(opt_idx); - if (is_tty_option(opt->fullname)) { - return SOPT_GLOBAL; - } - // Hidden option if (opt->var == NULL) { return 0; @@ -470,14 +468,11 @@ static bool option_has_scope(char *name, OptReqScope req_scope) /// buffer-local value depending on opt_scope). OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Error *err) { - OptVal retv = NIL_OPTVAL; - if (!option_has_scope(name, req_scope)) { - return retv; + return NIL_OPTVAL; } - if (get_tty_option(name, &retv.data.string.data)) { - retv.type = kOptValTypeString; - return retv; + if (is_tty_option(name)) { + return get_tty_option(name); } int opt_idx = findoption(name); @@ -490,11 +485,11 @@ OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Er : (req_scope == kOptReqBuf ? (void *)&aco : NULL); bool switched = switch_option_context(ctx, req_scope, from, err); if (ERROR_SET(err)) { - return retv; + return NIL_OPTVAL; } char *varp = get_varp_scope(opt, req_scope == kOptReqGlobal ? OPT_GLOBAL : OPT_LOCAL); - retv = optval_from_varp(opt_idx, varp); + OptVal retv = optval_from_varp(opt_idx, varp); if (switched) { restore_option_context(ctx, req_scope); @@ -505,7 +500,7 @@ OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Er /// Get option value for buffer / window. /// -/// @param[in] name Option name. +/// @param opt_idx Option index in options[] table. /// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). /// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). /// @param[out] hidden Whether option is hidden. @@ -514,8 +509,8 @@ OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Er /// @param[out] err Error message, if any. /// /// @return Option value. Must be freed by caller. -OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, bool *hidden, - const OptReqScope req_scope, void *const from, Error *err) +OptVal get_option_value_for(int opt_idx, int scope, const OptReqScope req_scope, void *const from, + Error *err) { switchwin_T switchwin; aco_save_T aco; @@ -527,7 +522,7 @@ OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, return NIL_OPTVAL; } - OptVal retv = get_option_value(name, flagsp, scope, hidden); + OptVal retv = get_option_value(opt_idx, scope); if (switched) { restore_option_context(ctx, req_scope); diff --git a/src/nvim/context.c b/src/nvim/context.c index 28a67061c6..63c0f8c20c 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -138,7 +138,7 @@ bool ctx_restore(Context *ctx, const int flags) free_ctx = true; } - OptVal op_shada = get_option_value("shada", NULL, OPT_GLOBAL, NULL); + OptVal op_shada = get_option_value(findoption("shada"), OPT_GLOBAL); set_option_value("shada", STATIC_CSTR_AS_OPTVAL("!,'100,%"), OPT_GLOBAL); if (flags & kCtxRegs) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ac1461056c..16c1231682 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3784,37 +3784,32 @@ int eval_option(const char **const arg, typval_T *const rettv, const bool evalua } int ret = OK; - bool hidden; char c = *option_end; *option_end = NUL; - OptVal value = get_option_value(*arg, NULL, scope, &hidden); - if (rettv != NULL) { - switch (value.type) { - case kOptValTypeNil: + bool is_tty_opt = is_tty_option(*arg); + int opt_idx = is_tty_opt ? -1 : findoption(*arg); + + if (opt_idx < 0 && !is_tty_opt) { + // Only give error if result is going to be used. + if (rettv != NULL) { semsg(_("E113: Unknown option: %s"), *arg); - ret = FAIL; - break; - case kOptValTypeBoolean: - rettv->v_type = VAR_NUMBER; - rettv->vval.v_number = value.data.boolean; - break; - case kOptValTypeNumber: - rettv->v_type = VAR_NUMBER; - rettv->vval.v_number = value.data.number; - break; - case kOptValTypeString: - rettv->v_type = VAR_STRING; - rettv->vval.v_string = value.data.string.data; - break; } - } else { - // Value isn't being used, free it. - optval_free(value); - if (value.type == kOptValTypeNil || (working && hidden)) { - ret = FAIL; + ret = FAIL; + } else if (rettv != NULL) { + OptVal value = is_tty_opt ? get_tty_option(*arg) : get_option_value(opt_idx, scope); + assert(value.type != kOptValTypeNil); + + *rettv = optval_as_tv(value); + + // Convert boolean option value to number for backwards compatibility. + if (rettv->v_type == VAR_BOOL) { + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = rettv->vval.v_bool == kBoolVarTrue ? 1 : 0; } + } else if (working && !is_tty_opt && is_option_hidden(opt_idx)) { + ret = FAIL; } *option_end = c; // put back for error messages diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 670ee39f4b..8864edbf69 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -773,11 +773,14 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, const char c1 = *p; *p = NUL; - uint32_t opt_p_flags; - bool hidden; - OptVal curval = get_option_value(arg, &opt_p_flags, scope, &hidden); + bool is_tty_opt = is_tty_option(arg); + int opt_idx = is_tty_opt ? -1 : findoption(arg); + uint32_t opt_p_flags = get_option_flags(opt_idx); + bool hidden = is_option_hidden(opt_idx); + OptVal curval = is_tty_opt ? get_tty_option(arg) : get_option_value(opt_idx, scope); OptVal newval = NIL_OPTVAL; - if (curval.type == kOptValTypeNil && arg[0] != 't' && arg[1] != '_') { + + if (curval.type == kOptValTypeNil) { semsg(_(e_unknown_option2), arg); goto theend; } diff --git a/src/nvim/option.c b/src/nvim/option.c index c9d65c5683..41d66adfc1 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3099,51 +3099,36 @@ int findoption_len(const char *const arg, const size_t len) bool is_tty_option(const char *name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - return (name[0] == 't' && name[1] == '_') - || strequal(name, "term") - || strequal(name, "ttytype"); + return (name[0] == 't' && name[1] == '_') || strequal(name, "term") || strequal(name, "ttytype"); } #define TCO_BUFFER_SIZE 8 -/// @param name TUI-related option -/// @param[out,allocated] value option string value -bool get_tty_option(const char *name, char **value) +/// Get value of TTY option. +/// +/// @param name Name of TTY option. +/// +/// @return [allocated] TTY option value. Returns NIL_OPTVAL if option isn't a TTY option. +OptVal get_tty_option(const char *name) { - if (strequal(name, "t_Co")) { - if (value) { - if (t_colors <= 1) { - *value = xstrdup(""); - } else { - *value = xmalloc(TCO_BUFFER_SIZE); - snprintf(*value, TCO_BUFFER_SIZE, "%d", t_colors); - } - } - return true; - } + char *value = NULL; - if (strequal(name, "term")) { - if (value) { - *value = p_term ? xstrdup(p_term) : xstrdup("nvim"); - } - return true; - } - - if (strequal(name, "ttytype")) { - if (value) { - *value = p_ttytype ? xstrdup(p_ttytype) : xstrdup("nvim"); - } - return true; - } - - if (is_tty_option(name)) { - if (value) { - // XXX: All other t_* options were removed in 3baba1e7. - *value = xstrdup(""); + if (strequal(name, "t_Co")) { + if (t_colors <= 1) { + value = xstrdup(""); + } else { + value = xmalloc(TCO_BUFFER_SIZE); + snprintf(value, TCO_BUFFER_SIZE, "%d", t_colors); } - return true; + } else if (strequal(name, "term")) { + value = p_term ? xstrdup(p_term) : xstrdup("nvim"); + } else if (strequal(name, "ttytype")) { + value = p_ttytype ? xstrdup(p_ttytype) : xstrdup("nvim"); + } else if (is_tty_option(name)) { + // XXX: All other t_* options were removed in 3baba1e7. + value = xstrdup(""); } - return false; + return value == NULL ? NIL_OPTVAL : CSTR_AS_OPTVAL(value); } bool set_tty_option(const char *name, char *value) @@ -3412,7 +3397,7 @@ static OptVal optval_unset_local(int opt_idx, void *varp) } } // For options that aren't global-local, just set the local value to the global value. - return get_option_value(opt->fullname, NULL, OPT_GLOBAL, NULL); + return get_option_value(opt_idx, OPT_GLOBAL); } /// Get an allocated string containing a list of valid types for an option. @@ -3458,46 +3443,41 @@ static char *option_get_valid_types(int opt_idx) #undef OPTION_ADD_TYPE } -/// Gets the value for an option. +/// Check if option is hidden. /// -/// @param[in] name Option name. -/// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). -/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). -/// @param[out] hidden Whether option is hidden. +/// @param opt_idx Option index in options[] table. /// -/// @return [allocated] Option value. Returns NIL_OPTVAL for invalid options. -OptVal get_option_value(const char *name, uint32_t *flagsp, int scope, bool *hidden) +/// @return True if option is hidden, false otherwise. Returns false if option name is invalid. +bool is_option_hidden(int opt_idx) { - // Make sure that hidden and flagsp are never returned uninitialized - if (hidden != NULL) { - *hidden = false; - } - if (flagsp != NULL) { - *flagsp = 0; - } + return opt_idx < 0 ? false : get_varp(&options[opt_idx]) == NULL; +} - char *str; - if (get_tty_option(name, &str)) { - return CSTR_AS_OPTVAL(str); - } +/// Get option flags. +/// +/// @param opt_idx Option index in options[] table. +/// +/// @return Option flags. Returns 0 for invalid option name. +uint32_t get_option_flags(int opt_idx) +{ + return opt_idx < 0 ? 0 : options[opt_idx].flags; +} - int opt_idx = findoption(name); - if (opt_idx < 0) { // option not in the table +/// Gets the value for an option. +/// +/// @param opt_idx Option index in options[] table. +/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). +/// +/// @return [allocated] Option value. Returns NIL_OPTVAL for invalid option index. +OptVal get_option_value(int opt_idx, int scope) +{ + if (opt_idx < 0) { // option not in the options[] table. return NIL_OPTVAL; } vimoption_T *opt = &options[opt_idx]; void *varp = get_varp_scope(opt, scope); - if (hidden != NULL) { - *hidden = varp == NULL; - } - - if (flagsp != NULL) { - // Return the P_xxxx option flags. - *flagsp = opt->flags; - } - return optval_copy(optval_from_varp(opt_idx, varp)); } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 5065bee347..eb3bcec3ec 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3218,7 +3218,7 @@ void ex_spelldump(exarg_T *eap) if (no_spell_checking(curwin)) { return; } - OptVal spl = get_option_value("spl", NULL, OPT_LOCAL, NULL); + OptVal spl = get_option_value(findoption("spl"), OPT_LOCAL); // Create a new empty buffer in a new window. do_cmdline_cmd("new"); -- cgit From 999e167a521a9dd88a1e3fb7814c5a8960e820b1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 8 Dec 2023 10:25:38 +0800 Subject: fix(tui): start flush earlier (#26463) Problem: TUI flush (start sync or hide cursor) only starts on a "flush" event, which is too late. Solution: Start the next flush when anything will be drawn. --- src/nvim/tui/tui.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index f500994229..b7da3e4b96 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -76,8 +76,9 @@ struct TUIData { size_t bufpos; TermInput input; uv_loop_t write_loop; + bool dirty; ///< whether there has been drawing since the last tui_flush() unibi_term *ut; - char *term; // value of $TERM + char *term; ///< value of $TERM union { uv_tty_t tty; uv_pipe_t pipe; @@ -900,6 +901,8 @@ static void print_cell_at_pos(TUIData *tui, int row, int col, UCell *cell, bool return; } + tui_set_dirty(tui); + cursor_goto(tui, row, col); char buf[MAX_SCHAR_SIZE]; @@ -925,6 +928,8 @@ static void clear_region(TUIData *tui, int top, int bot, int left, int right, in { UGrid *grid = &tui->grid; + tui_set_dirty(tui); + update_attrs(tui, attr_id); // Background is set to the default color and the right edge matches the @@ -1242,6 +1247,8 @@ void tui_grid_scroll(TUIData *tui, Integer g, Integer startrow, Integer endrow, || tui->can_set_left_right_margin))); if (can_scroll) { + tui_set_dirty(tui); + // Change terminal scroll region and move cursor to the top if (!tui->scroll_region_is_full_screen) { set_scroll_region(tui, top, bot, left, right); @@ -1311,6 +1318,15 @@ void tui_default_colors_set(TUIData *tui, Integer rgb_fg, Integer rgb_bg, Intege invalidate(tui, 0, tui->grid.height, 0, tui->grid.width); } +static void tui_set_dirty(TUIData *tui) + FUNC_ATTR_NONNULL_ALL +{ + if (!tui->dirty) { + tui->dirty = true; + tui_flush_start(tui); + } +} + /// Begin flushing the TUI. If 'termsync' is set and the terminal supports synchronized updates, /// begin a synchronized update. Otherwise, hide the cursor to avoid cursor jumping. static void tui_flush_start(TUIData *tui) @@ -1360,7 +1376,7 @@ void tui_flush(TUIData *tui) tui_busy_stop(tui); // avoid hidden cursor } - tui_flush_start(tui); + tui_set_dirty(tui); while (kv_size(tui->invalid_regions)) { Rect r = kv_pop(tui->invalid_regions); @@ -1389,9 +1405,10 @@ void tui_flush(TUIData *tui) cursor_goto(tui, tui->row, tui->col); + assert(tui->dirty); tui_flush_end(tui); - flush_buf(tui); + tui->dirty = false; } /// Dumps termcap info to the messages area, if 'verbose' >= 3. -- cgit From 2289ca273cdaad4248a6cd962bddcc956b296c18 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Fri, 8 Dec 2023 05:58:29 +0100 Subject: perf(column): avoid counting when max signs are removed from a range --- src/nvim/decoration.c | 32 ++++++++++++++++++++------------ src/nvim/drawscreen.c | 8 +++----- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 20311d80e5..62cbd33186 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -792,17 +792,16 @@ DecorSignHighlight *decor_find_sign(DecorInline decor) } } -/// If "count" is greater than current max, set it and reset "max_count". static void buf_signcols_validate_row(buf_T *buf, int count, int add) { - int del = add < 0 ? -add : 0; + // If "count" is greater than current max, set it and reset "max_count". if (count > buf->b_signcols.max) { buf->b_signcols.max = count; buf->b_signcols.max_count = 0; buf->b_signcols.resized = true; } - /// Add sign of "add" to "max_count" - if (count == buf->b_signcols.max - del) { + // If row has or had "max" signs, adjust "max_count" with sign of "add". + if (count == buf->b_signcols.max - (add < 0 ? -add : 0)) { buf->b_signcols.max_count += (add > 0) - (add < 0); } } @@ -811,7 +810,12 @@ static void buf_signcols_validate_row(buf_T *buf, int count, int add) /// "b_signcols" accordingly. static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) { - int count = 0; // Number of signs on the current line + if (-add == buf->b_signcols.max) { + buf->b_signcols.max_count -= (row2 + 1 - row1); + return; // max signs were removed from the range, no need to count. + } + + int count = 0; // Number of signs on the current row int currow = row1; MTPair pair = { 0 }; MarkTreeIter itr[1]; @@ -847,8 +851,8 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) count++; if (mt_paired(mark)) { MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL); - for (int i = mark.pos.row; i < MIN(row2, end.row); i++) { - overlap[row2 - i]++; + for (int i = mark.pos.row + 1; i <= MIN(row2, end.row); i++) { + overlap[i - row1]++; } } } @@ -861,13 +865,17 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) int buf_signcols_validate(win_T *wp, buf_T *buf, bool stc_check) { + if (!map_size(buf->b_signcols.invalid)) { + return buf->b_signcols.max; + } + int start; SignRange range; map_foreach(buf->b_signcols.invalid, start, range, { - // Leave rest of the ranges invalid if max is already greater than - // configured maximum or resize is detected for 'statuscolumn' rebuild. - if ((!stc_check || buf->b_signcols.resized) - && (range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) { + // Leave rest of the ranges invalid if max is already at configured + // maximum or resize is detected for a 'statuscolumn' rebuild. + if ((stc_check && buf->b_signcols.resized) + || (!stc_check && range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) { return wp->w_maxscwidth; } buf_signcols_validate_range(buf, start, range.end, range.add); @@ -877,7 +885,7 @@ int buf_signcols_validate(win_T *wp, buf_T *buf, bool stc_check) if (buf->b_signcols.max_count == 0) { buf->b_signcols.max = 0; buf->b_signcols.resized = true; - buf_signcols_validate_range(buf, 0, buf->b_ml.ml_line_count, 0); + buf_signcols_validate_range(buf, 0, buf->b_ml.ml_line_count, 1); } map_clear(int, buf->b_signcols.invalid); diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index a436dd2766..314764d117 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1195,15 +1195,13 @@ void comp_col(void) /// Redraw entire window "wp" if configured 'signcolumn' width changes. static bool win_redraw_signcols(win_T *wp) { + int width; bool rebuild_stc = false; buf_T *buf = wp->w_buffer; - int width = buf->b_signcols.max; if (wp->w_minscwidth <= SCL_NO) { if (*wp->w_p_stc) { - if (map_size(buf->b_signcols.invalid)) { - buf_signcols_validate(wp, buf, true); - } + buf_signcols_validate(wp, buf, true); if (buf->b_signcols.resized) { rebuild_stc = true; wp->w_nrwidth_line_count = 0; @@ -1212,7 +1210,7 @@ static bool win_redraw_signcols(win_T *wp) width = 0; } else if (wp->w_maxscwidth <= 1 && buf->b_signs_with_text >= (size_t)wp->w_maxscwidth) { width = wp->w_maxscwidth; - } else if (map_size(buf->b_signcols.invalid)) { + } else { width = buf_signcols_validate(wp, buf, false); } -- cgit From b8e227b621468a6ce968f631e4b933f7c12e6955 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 9 Dec 2023 07:18:21 +0800 Subject: vim-patch:9.0.2154: The option[] array is not sorted (#26475) Problem: The options[] array is not sorted alphabetically. Solution: Sort it alphabetically. Add a test. Avoid unnecessary loop iterations in findoption(). closes: vim/vim#13648 Cherry-pick Test_set_one_column() change from patch 8.2.0432. https://github.com/vim/vim/commit/f48558e10a08a1a483e25ef847bbceeac6b44561 --- src/nvim/option.c | 5 +- src/nvim/options.lua | 582 +++++++++++++++++++++++++-------------------------- 2 files changed, 295 insertions(+), 292 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 41d66adfc1..b5291f616b 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3065,11 +3065,14 @@ int findoption_len(const char *const arg, const size_t len) opt_idx = quick_tab[CHAR_ORD_LOW(arg[0])]; } // Match full name - for (; (s = options[opt_idx].fullname) != NULL; opt_idx++) { + for (; (s = options[opt_idx].fullname) != NULL && s[0] == arg[0]; opt_idx++) { if (strncmp(arg, s, len) == 0 && s[len] == NUL) { break; } } + if (s != NULL && s[0] != arg[0]) { + s = NULL; + } if (s == NULL && !is_term_opt) { opt_idx = quick_tab[CHAR_ORD_LOW(arg[0])]; // Match short name diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 50371b8bf3..8f0be0eb1b 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -93,56 +93,6 @@ return { short_desc = N_('ASCII code of the letter Aleph (Hebrew)'), type = 'number', }, - { - abbreviation = 'arab', - cb = 'did_set_arabic', - defaults = { if_true = false }, - desc = [=[ - This option can be set to start editing Arabic text. - Setting this option will: - - Set the 'rightleft' option, unless 'termbidi' is set. - - Set the 'arabicshape' option, unless 'termbidi' is set. - - Set the 'keymap' option to "arabic"; in Insert mode CTRL-^ toggles - between typing English and Arabic key mapping. - - Set the 'delcombine' option - - Resetting this option will: - - Reset the 'rightleft' option. - - Disable the use of 'keymap' (without changing its value). - Note that 'arabicshape' and 'delcombine' are not reset (it is a global - option). - Also see |arabic.txt|. - ]=], - full_name = 'arabic', - redraw = { 'curswant' }, - scope = { 'window' }, - short_desc = N_('Arabic as a default second language'), - type = 'bool', - }, - { - abbreviation = 'arshape', - defaults = { if_true = true }, - desc = [=[ - When on and 'termbidi' is off, the required visual character - corrections that need to take place for displaying the Arabic language - take effect. Shaping, in essence, gets enabled; the term is a broad - one which encompasses: - a) the changing/morphing of characters based on their location - within a word (initial, medial, final and stand-alone). - b) the enabling of the ability to compose characters - c) the enabling of the required combining of some characters - When disabled the display shows each character's true stand-alone - form. - Arabic is a complex language which requires other settings, for - further details see |arabic.txt|. - ]=], - full_name = 'arabicshape', - redraw = { 'all_windows', 'ui_option' }, - scope = { 'global' }, - short_desc = N_('do shaping for Arabic characters'), - type = 'bool', - varname = 'p_arshape', - }, { abbreviation = 'ari', defaults = { if_true = false }, @@ -202,6 +152,56 @@ return { type = 'string', varname = 'p_ambw', }, + { + abbreviation = 'arab', + cb = 'did_set_arabic', + defaults = { if_true = false }, + desc = [=[ + This option can be set to start editing Arabic text. + Setting this option will: + - Set the 'rightleft' option, unless 'termbidi' is set. + - Set the 'arabicshape' option, unless 'termbidi' is set. + - Set the 'keymap' option to "arabic"; in Insert mode CTRL-^ toggles + between typing English and Arabic key mapping. + - Set the 'delcombine' option + + Resetting this option will: + - Reset the 'rightleft' option. + - Disable the use of 'keymap' (without changing its value). + Note that 'arabicshape' and 'delcombine' are not reset (it is a global + option). + Also see |arabic.txt|. + ]=], + full_name = 'arabic', + redraw = { 'curswant' }, + scope = { 'window' }, + short_desc = N_('Arabic as a default second language'), + type = 'bool', + }, + { + abbreviation = 'arshape', + defaults = { if_true = true }, + desc = [=[ + When on and 'termbidi' is off, the required visual character + corrections that need to take place for displaying the Arabic language + take effect. Shaping, in essence, gets enabled; the term is a broad + one which encompasses: + a) the changing/morphing of characters based on their location + within a word (initial, medial, final and stand-alone). + b) the enabling of the ability to compose characters + c) the enabling of the required combining of some characters + When disabled the display shows each character's true stand-alone + form. + Arabic is a complex language which requires other settings, for + further details see |arabic.txt|. + ]=], + full_name = 'arabicshape', + redraw = { 'all_windows', 'ui_option' }, + scope = { 'global' }, + short_desc = N_('do shaping for Arabic characters'), + type = 'bool', + varname = 'p_arshape', + }, { abbreviation = 'acd', cb = 'did_set_autochdir', @@ -1128,6 +1128,25 @@ return { type = 'string', varname = 'p_cino', }, + { + abbreviation = 'cinsd', + alloced = true, + defaults = { if_true = 'public,protected,private' }, + deny_duplicates = true, + desc = [=[ + Keywords that are interpreted as a C++ scope declaration by |cino-g|. + Useful e.g. for working with the Qt framework that defines additional + scope declarations "signals", "public slots" and "private slots": > + set cinscopedecls+=signals,public\ slots,private\ slots + < + ]=], + full_name = 'cinscopedecls', + list = 'onecomma', + scope = { 'buffer' }, + short_desc = N_("words that are recognized by 'cino-g'"), + type = 'string', + varname = 'p_cinsd', + }, { abbreviation = 'cinw', alloced = true, @@ -1148,25 +1167,6 @@ return { type = 'string', varname = 'p_cinw', }, - { - abbreviation = 'cinsd', - alloced = true, - defaults = { if_true = 'public,protected,private' }, - deny_duplicates = true, - desc = [=[ - Keywords that are interpreted as a C++ scope declaration by |cino-g|. - Useful e.g. for working with the Qt framework that defines additional - scope declarations "signals", "public slots" and "private slots": > - set cinscopedecls+=signals,public\ slots,private\ slots - < - ]=], - full_name = 'cinscopedecls', - list = 'onecomma', - scope = { 'buffer' }, - short_desc = N_("words that are recognized by 'cino-g'"), - type = 'string', - varname = 'p_cinsd', - }, { abbreviation = 'cb', cb = 'did_set_clipboard', @@ -1393,65 +1393,6 @@ return { type = 'string', varname = 'p_cpt', }, - { - abbreviation = 'cocu', - alloced = true, - cb = 'did_set_concealcursor', - defaults = { if_true = '' }, - desc = [=[ - Sets the modes in which text in the cursor line can also be concealed. - When the current mode is listed then concealing happens just like in - other lines. - n Normal mode - v Visual mode - i Insert mode - c Command line editing, for 'incsearch' - - 'v' applies to all lines in the Visual area, not only the cursor. - A useful value is "nc". This is used in help files. So long as you - are moving around text is concealed, but when starting to insert text - or selecting a Visual area the concealed text is displayed, so that - you can see what you are doing. - Keep in mind that the cursor position is not always where it's - displayed. E.g., when moving vertically it may change column. - ]=], - expand_cb = 'expand_set_concealcursor', - full_name = 'concealcursor', - list = 'flags', - redraw = { 'current_window' }, - scope = { 'window' }, - short_desc = N_('whether concealable text is hidden in cursor line'), - type = 'string', - }, - { - abbreviation = 'cole', - defaults = { if_true = 0 }, - desc = [=[ - Determine how text with the "conceal" syntax attribute |:syn-conceal| - is shown: - - Value Effect ~ - 0 Text is shown normally - 1 Each block of concealed text is replaced with one - character. If the syntax item does not have a custom - replacement character defined (see |:syn-cchar|) the - character defined in 'listchars' is used. - It is highlighted with the "Conceal" highlight group. - 2 Concealed text is completely hidden unless it has a - custom replacement character defined (see - |:syn-cchar|). - 3 Concealed text is completely hidden. - - Note: in the cursor line concealed text is not hidden, so that you can - edit and copy the text. This can be changed with the 'concealcursor' - option. - ]=], - full_name = 'conceallevel', - redraw = { 'current_window' }, - scope = { 'window' }, - short_desc = N_('whether concealable text is shown or hidden'), - type = 'number', - }, { abbreviation = 'cfu', alloced = true, @@ -1542,6 +1483,65 @@ return { type = 'string', varname = 'p_csl', }, + { + abbreviation = 'cocu', + alloced = true, + cb = 'did_set_concealcursor', + defaults = { if_true = '' }, + desc = [=[ + Sets the modes in which text in the cursor line can also be concealed. + When the current mode is listed then concealing happens just like in + other lines. + n Normal mode + v Visual mode + i Insert mode + c Command line editing, for 'incsearch' + + 'v' applies to all lines in the Visual area, not only the cursor. + A useful value is "nc". This is used in help files. So long as you + are moving around text is concealed, but when starting to insert text + or selecting a Visual area the concealed text is displayed, so that + you can see what you are doing. + Keep in mind that the cursor position is not always where it's + displayed. E.g., when moving vertically it may change column. + ]=], + expand_cb = 'expand_set_concealcursor', + full_name = 'concealcursor', + list = 'flags', + redraw = { 'current_window' }, + scope = { 'window' }, + short_desc = N_('whether concealable text is hidden in cursor line'), + type = 'string', + }, + { + abbreviation = 'cole', + defaults = { if_true = 0 }, + desc = [=[ + Determine how text with the "conceal" syntax attribute |:syn-conceal| + is shown: + + Value Effect ~ + 0 Text is shown normally + 1 Each block of concealed text is replaced with one + character. If the syntax item does not have a custom + replacement character defined (see |:syn-cchar|) the + character defined in 'listchars' is used. + It is highlighted with the "Conceal" highlight group. + 2 Concealed text is completely hidden unless it has a + custom replacement character defined (see + |:syn-cchar|). + 3 Concealed text is completely hidden. + + Note: in the cursor line concealed text is not hidden, so that you can + edit and copy the text. This can be changed with the 'concealcursor' + option. + ]=], + full_name = 'conceallevel', + redraw = { 'current_window' }, + scope = { 'window' }, + short_desc = N_('whether concealable text is shown or hidden'), + type = 'number', + }, { abbreviation = 'cf', defaults = { if_true = false }, @@ -3240,27 +3240,6 @@ return { type = 'string', varname = 'p_fex', }, - { - abbreviation = 'fo', - alloced = true, - cb = 'did_set_formatoptions', - defaults = { if_true = macros('DFLT_FO_VIM') }, - desc = [=[ - This is a sequence of letters which describes how automatic - formatting is to be done. - See |fo-table| for possible values and |gq| for how to format text. - Commas can be inserted for readability. - To avoid problems with flags that are added in the future, use the - "+=" and "-=" feature of ":set" |add-option-flags|. - ]=], - expand_cb = 'expand_set_formatoptions', - full_name = 'formatoptions', - list = 'flags', - scope = { 'buffer' }, - short_desc = N_('how automatic formatting is to be done'), - type = 'string', - varname = 'p_fo', - }, { abbreviation = 'flp', alloced = true, @@ -3282,6 +3261,27 @@ return { type = 'string', varname = 'p_flp', }, + { + abbreviation = 'fo', + alloced = true, + cb = 'did_set_formatoptions', + defaults = { if_true = macros('DFLT_FO_VIM') }, + desc = [=[ + This is a sequence of letters which describes how automatic + formatting is to be done. + See |fo-table| for possible values and |gq| for how to format text. + Commas can be inserted for readability. + To avoid problems with flags that are added in the future, use the + "+=" and "-=" feature of ":set" |add-option-flags|. + ]=], + expand_cb = 'expand_set_formatoptions', + full_name = 'formatoptions', + list = 'flags', + scope = { 'buffer' }, + short_desc = N_('how automatic formatting is to be done'), + type = 'string', + varname = 'p_fo', + }, { abbreviation = 'fp', defaults = { if_true = '' }, @@ -6556,27 +6556,6 @@ return { short_desc = N_('lines to scroll with CTRL-U and CTRL-D'), type = 'number', }, - { - abbreviation = 'sms', - cb = 'did_set_smoothscroll', - defaults = { if_true = false }, - desc = [=[ - Scrolling works with screen lines. When 'wrap' is set and the first - line in the window wraps part of it may not be visible, as if it is - above the window. "<<<" is displayed at the start of the first line, - highlighted with |hl-NonText|. - You may also want to add "lastline" to the 'display' option to show as - much of the last line as possible. - NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y - and scrolling with the mouse. - ]=], - full_name = 'smoothscroll', - pv_name = 'p_sms', - redraw = { 'current_window' }, - scope = { 'window' }, - short_desc = N_("scroll by screen lines when 'wrap' is set"), - type = 'bool', - }, { abbreviation = 'scbk', cb = 'did_set_scrollback', @@ -7229,6 +7208,23 @@ return { type = 'bool', varname = 'p_stmp', }, + { + abbreviation = 'sxe', + defaults = { if_true = '' }, + desc = [=[ + When 'shellxquote' is set to "(" then the characters listed in this + option will be escaped with a '^' character. This makes it possible + to execute most external commands with cmd.exe. + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. + ]=], + full_name = 'shellxescape', + scope = { 'global' }, + secure = true, + short_desc = N_("characters to escape when 'shellxquote' is ("), + type = 'string', + varname = 'p_sxe', + }, { abbreviation = 'sxq', defaults = { @@ -7255,23 +7251,6 @@ return { type = 'string', varname = 'p_sxq', }, - { - abbreviation = 'sxe', - defaults = { if_true = '' }, - desc = [=[ - When 'shellxquote' is set to "(" then the characters listed in this - option will be escaped with a '^' character. This makes it possible - to execute most external commands with cmd.exe. - This option cannot be set from a |modeline| or in the |sandbox|, for - security reasons. - ]=], - full_name = 'shellxescape', - scope = { 'global' }, - secure = true, - short_desc = N_("characters to escape when 'shellxquote' is ("), - type = 'string', - varname = 'p_sxe', - }, { abbreviation = 'sr', defaults = { if_true = false }, @@ -7667,6 +7646,27 @@ return { type = 'bool', varname = 'p_sta', }, + { + abbreviation = 'sms', + cb = 'did_set_smoothscroll', + defaults = { if_true = false }, + desc = [=[ + Scrolling works with screen lines. When 'wrap' is set and the first + line in the window wraps part of it may not be visible, as if it is + above the window. "<<<" is displayed at the start of the first line, + highlighted with |hl-NonText|. + You may also want to add "lastline" to the 'display' option to show as + much of the last line as possible. + NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y + and scrolling with the mouse. + ]=], + full_name = 'smoothscroll', + pv_name = 'p_sms', + redraw = { 'current_window' }, + scope = { 'window' }, + short_desc = N_("scroll by screen lines when 'wrap' is set"), + type = 'bool', + }, { abbreviation = 'sts', defaults = { if_true = 0 }, @@ -7820,6 +7820,31 @@ return { type = 'string', varname = 'p_spl', }, + { + abbreviation = 'spo', + cb = 'did_set_spelloptions', + defaults = { if_true = '' }, + deny_duplicates = true, + desc = [=[ + A comma-separated list of options for spell checking: + camel When a word is CamelCased, assume "Cased" is a + separate word: every upper-case character in a word + that comes after a lower case character indicates the + start of a new word. + noplainbuffer Only spellcheck a buffer when 'syntax' is enabled, + or when extmarks are set within the buffer. Only + designated regions of the buffer are spellchecked in + this case. + ]=], + expand_cb = 'expand_set_spelloptions', + full_name = 'spelloptions', + list = 'onecomma', + redraw = { 'current_buffer' }, + scope = { 'buffer' }, + secure = true, + type = 'string', + varname = 'p_spo', + }, { abbreviation = 'sps', cb = 'did_set_spellsuggest', @@ -7900,31 +7925,6 @@ return { type = 'string', varname = 'p_sps', }, - { - abbreviation = 'spo', - cb = 'did_set_spelloptions', - defaults = { if_true = '' }, - deny_duplicates = true, - desc = [=[ - A comma-separated list of options for spell checking: - camel When a word is CamelCased, assume "Cased" is a - separate word: every upper-case character in a word - that comes after a lower case character indicates the - start of a new word. - noplainbuffer Only spellcheck a buffer when 'syntax' is enabled, - or when extmarks are set within the buffer. Only - designated regions of the buffer are spellchecked in - this case. - ]=], - expand_cb = 'expand_set_spelloptions', - full_name = 'spelloptions', - list = 'onecomma', - redraw = { 'current_buffer' }, - scope = { 'buffer' }, - secure = true, - type = 'string', - varname = 'p_spo', - }, { abbreviation = 'sb', defaults = { if_true = false }, @@ -8455,28 +8455,6 @@ return { type = 'string', varname = 'p_syn', }, - { - abbreviation = 'tfu', - cb = 'did_set_tagfunc', - defaults = { if_true = '' }, - desc = [=[ - This option specifies a function to be used to perform tag searches. - The function gets the tag pattern and should return a List of matching - tags. See |tag-function| for an explanation of how to write the - function and an example. The value can be the name of a function, a - |lambda| or a |Funcref|. See |option-value-function| for more - information. - This option cannot be set from a |modeline| or in the |sandbox|, for - security reasons. - ]=], - full_name = 'tagfunc', - func = true, - scope = { 'buffer' }, - secure = true, - short_desc = N_('function used to perform tag searches'), - type = 'string', - varname = 'p_tfu', - }, { abbreviation = 'tal', cb = 'did_set_tabline', @@ -8655,6 +8633,28 @@ return { type = 'string', varname = 'p_tc', }, + { + abbreviation = 'tfu', + cb = 'did_set_tagfunc', + defaults = { if_true = '' }, + desc = [=[ + This option specifies a function to be used to perform tag searches. + The function gets the tag pattern and should return a List of matching + tags. See |tag-function| for an explanation of how to write the + function and an example. The value can be the name of a function, a + |lambda| or a |Funcref|. See |option-value-function| for more + information. + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. + ]=], + full_name = 'tagfunc', + func = true, + scope = { 'buffer' }, + secure = true, + short_desc = N_('function used to perform tag searches'), + type = 'string', + varname = 'p_tfu', + }, { abbreviation = 'tl', defaults = { if_true = 0 }, @@ -9792,39 +9792,6 @@ return { short_desc = N_('Controls transparency level for floating windows'), type = 'number', }, - { - abbreviation = 'winhl', - alloced = true, - cb = 'did_set_winhighlight', - defaults = { if_true = '' }, - deny_duplicates = true, - desc = [=[ - Window-local highlights. Comma-delimited list of highlight - |group-name| pairs "{hl-from}:{hl-to},..." where each {hl-from} is - a |highlight-groups| item to be overridden by {hl-to} group in - the window. - - Note: highlight namespaces take precedence over 'winhighlight'. - See |nvim_win_set_hl_ns()| and |nvim_set_hl()|. - - Highlights of vertical separators are determined by the window to the - left of the separator. The 'tabline' highlight of a tabpage is - decided by the last-focused window of the tabpage. Highlights of - the popupmenu are determined by the current window. Highlights in the - message area cannot be overridden. - - Example: show a different color for non-current windows: > - set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC - < - ]=], - expand_cb = 'expand_set_winhighlight', - full_name = 'winhighlight', - list = 'onecommacolon', - redraw = { 'current_window' }, - scope = { 'window' }, - short_desc = N_('Setup window-local highlights'), - type = 'string', - }, { abbreviation = 'wi', cb = 'did_set_window', @@ -9849,6 +9816,35 @@ return { type = 'number', varname = 'p_window', }, + { + abbreviation = 'wfh', + defaults = { if_true = false }, + desc = [=[ + Keep the window height when windows are opened or closed and + 'equalalways' is set. Also for |CTRL-W_=|. Set by default for the + |preview-window| and |quickfix-window|. + The height may be changed anyway when running out of room. + ]=], + full_name = 'winfixheight', + redraw = { 'statuslines' }, + scope = { 'window' }, + short_desc = N_('keep window height when opening/closing windows'), + type = 'bool', + }, + { + abbreviation = 'wfw', + defaults = { if_true = false }, + desc = [=[ + Keep the window width when windows are opened or closed and + 'equalalways' is set. Also for |CTRL-W_=|. + The width may be changed anyway when running out of room. + ]=], + full_name = 'winfixwidth', + redraw = { 'statuslines' }, + scope = { 'window' }, + short_desc = N_('keep window width when opening/closing windows'), + type = 'bool', + }, { abbreviation = 'wh', cb = 'did_set_winheight', @@ -9879,33 +9875,37 @@ return { varname = 'p_wh', }, { - abbreviation = 'wfh', - defaults = { if_true = false }, - desc = [=[ - Keep the window height when windows are opened or closed and - 'equalalways' is set. Also for |CTRL-W_=|. Set by default for the - |preview-window| and |quickfix-window|. - The height may be changed anyway when running out of room. - ]=], - full_name = 'winfixheight', - redraw = { 'statuslines' }, - scope = { 'window' }, - short_desc = N_('keep window height when opening/closing windows'), - type = 'bool', - }, - { - abbreviation = 'wfw', - defaults = { if_true = false }, + abbreviation = 'winhl', + alloced = true, + cb = 'did_set_winhighlight', + defaults = { if_true = '' }, + deny_duplicates = true, desc = [=[ - Keep the window width when windows are opened or closed and - 'equalalways' is set. Also for |CTRL-W_=|. - The width may be changed anyway when running out of room. + Window-local highlights. Comma-delimited list of highlight + |group-name| pairs "{hl-from}:{hl-to},..." where each {hl-from} is + a |highlight-groups| item to be overridden by {hl-to} group in + the window. + + Note: highlight namespaces take precedence over 'winhighlight'. + See |nvim_win_set_hl_ns()| and |nvim_set_hl()|. + + Highlights of vertical separators are determined by the window to the + left of the separator. The 'tabline' highlight of a tabpage is + decided by the last-focused window of the tabpage. Highlights of + the popupmenu are determined by the current window. Highlights in the + message area cannot be overridden. + + Example: show a different color for non-current windows: > + set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC + < ]=], - full_name = 'winfixwidth', - redraw = { 'statuslines' }, + expand_cb = 'expand_set_winhighlight', + full_name = 'winhighlight', + list = 'onecommacolon', + redraw = { 'current_window' }, scope = { 'window' }, - short_desc = N_('keep window width when opening/closing windows'), - type = 'bool', + short_desc = N_('Setup window-local highlights'), + type = 'string', }, { abbreviation = 'wmh', -- cgit From c651fb30427a3c645b4b1bd8a9b7e767af51e014 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Fri, 8 Dec 2023 18:44:16 -0800 Subject: refactor(tui): use synchronized updates around actual buf flush (#26478) Rather than writing the synchronized update begin and end sequences into the TUI's internal buffer (where it is later flushed to the TTY), write these sequences directly to the TTY before and after the TUI's internal buffer is itself flushed to the TTY. This guarantees that a synchronized update is always used when we are actually sending data to the TTY. This means we do not need to keep track of the TUI's "dirty" state (any sequences which affect the TUI state will be written in the TUI's internal buffer, which is now guaranteed to only ever be written when a synchronized update is active). --- src/nvim/tui/tui.c | 137 +++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index b7da3e4b96..eac59eacac 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -42,9 +42,6 @@ # include "nvim/os/tty.h" #endif -// Space reserved in two output buffers to make the cursor normal or invisible -// when flushing. No existing terminal will require 32 bytes to do that. -#define CNORM_COMMAND_MAX_SIZE 32 #define OUTBUF_SIZE 0xffff #define TOO_MANY_EVENTS 1000000 @@ -76,7 +73,6 @@ struct TUIData { size_t bufpos; TermInput input; uv_loop_t write_loop; - bool dirty; ///< whether there has been drawing since the last tui_flush() unibi_term *ut; char *term; ///< value of $TERM union { @@ -901,8 +897,6 @@ static void print_cell_at_pos(TUIData *tui, int row, int col, UCell *cell, bool return; } - tui_set_dirty(tui); - cursor_goto(tui, row, col); char buf[MAX_SCHAR_SIZE]; @@ -928,8 +922,6 @@ static void clear_region(TUIData *tui, int top, int bot, int left, int right, in { UGrid *grid = &tui->grid; - tui_set_dirty(tui); - update_attrs(tui, attr_id); // Background is set to the default color and the right edge matches the @@ -1247,8 +1239,6 @@ void tui_grid_scroll(TUIData *tui, Integer g, Integer startrow, Integer endrow, || tui->can_set_left_right_margin))); if (can_scroll) { - tui_set_dirty(tui); - // Change terminal scroll region and move cursor to the top if (!tui->scroll_region_is_full_screen) { set_scroll_region(tui, top, bot, left, right); @@ -1318,48 +1308,6 @@ void tui_default_colors_set(TUIData *tui, Integer rgb_fg, Integer rgb_bg, Intege invalidate(tui, 0, tui->grid.height, 0, tui->grid.width); } -static void tui_set_dirty(TUIData *tui) - FUNC_ATTR_NONNULL_ALL -{ - if (!tui->dirty) { - tui->dirty = true; - tui_flush_start(tui); - } -} - -/// Begin flushing the TUI. If 'termsync' is set and the terminal supports synchronized updates, -/// begin a synchronized update. Otherwise, hide the cursor to avoid cursor jumping. -static void tui_flush_start(TUIData *tui) - FUNC_ATTR_NONNULL_ALL -{ - if (tui->sync_output && tui->unibi_ext.sync != -1) { - UNIBI_SET_NUM_VAR(tui->params[0], 1); - unibi_out_ext(tui, tui->unibi_ext.sync); - } else if (!tui->is_invisible) { - unibi_out(tui, unibi_cursor_invisible); - tui->is_invisible = true; - } -} - -/// Finish flushing the TUI. If 'termsync' is set and the terminal supports synchronized updates, -/// end a synchronized update. Otherwise, make the cursor visible again. -static void tui_flush_end(TUIData *tui) - FUNC_ATTR_NONNULL_ALL -{ - if (tui->sync_output && tui->unibi_ext.sync != -1) { - UNIBI_SET_NUM_VAR(tui->params[0], 0); - unibi_out_ext(tui, tui->unibi_ext.sync); - } - bool should_invisible = tui->busy || tui->want_invisible; - if (tui->is_invisible && !should_invisible) { - unibi_out(tui, unibi_cursor_normal); - tui->is_invisible = false; - } else if (!tui->is_invisible && should_invisible) { - unibi_out(tui, unibi_cursor_invisible); - tui->is_invisible = true; - } -} - void tui_flush(TUIData *tui) { UGrid *grid = &tui->grid; @@ -1376,8 +1324,6 @@ void tui_flush(TUIData *tui) tui_busy_stop(tui); // avoid hidden cursor } - tui_set_dirty(tui); - while (kv_size(tui->invalid_regions)) { Rect r = kv_pop(tui->invalid_regions); assert(r.bot <= grid->height && r.right <= grid->width); @@ -1405,10 +1351,7 @@ void tui_flush(TUIData *tui) cursor_goto(tui, tui->row, tui->col); - assert(tui->dirty); - tui_flush_end(tui); flush_buf(tui); - tui->dirty = false; } /// Dumps termcap info to the messages area, if 'verbose' >= 3. @@ -2312,23 +2255,93 @@ static void augment_terminfo(TUIData *tui, const char *term, int vte_version, in } } +/// Write the sequence to begin flushing output to `buf`. +/// If 'termsync' is set and the terminal supports synchronized output, begin synchronized update. +/// Otherwise, hide the cursor to avoid cursor jumping. +/// +/// @param buf the buffer to write the sequence to +/// @param len the length of `buf` +static size_t flush_buf_start(TUIData *tui, char *buf, size_t len) + FUNC_ATTR_NONNULL_ALL +{ + const char *str = NULL; + + if (tui->sync_output && tui->unibi_ext.sync != -1) { + UNIBI_SET_NUM_VAR(tui->params[0], 1); + str = unibi_get_ext_str(tui->ut, (size_t)tui->unibi_ext.sync); + } else if (!tui->is_invisible) { + str = unibi_get_str(tui->ut, unibi_cursor_invisible); + tui->is_invisible = true; + } + + if (str == NULL) { + return 0; + } + + return unibi_run(str, tui->params, buf, len); +} + +/// Write the sequence to end flushing output to `buf`. +/// If 'termsync' is set and the terminal supports synchronized output, end synchronized update. +/// Otherwise, make the cursor visible again. +/// +/// @param buf the buffer to write the sequence to +/// @param len the length of `buf` +static size_t flush_buf_end(TUIData *tui, char *buf, size_t len) + FUNC_ATTR_NONNULL_ALL +{ + size_t offset = 0; + if (tui->sync_output && tui->unibi_ext.sync != -1) { + UNIBI_SET_NUM_VAR(tui->params[0], 0); + const char *str = unibi_get_ext_str(tui->ut, (size_t)tui->unibi_ext.sync); + offset = unibi_run(str, tui->params, buf, len); + } + + const char *str = NULL; + bool should_invisible = tui->busy || tui->want_invisible; + if (tui->is_invisible && !should_invisible) { + str = unibi_get_str(tui->ut, unibi_cursor_normal); + tui->is_invisible = false; + } else if (!tui->is_invisible && should_invisible) { + str = unibi_get_str(tui->ut, unibi_cursor_invisible); + tui->is_invisible = true; + } + + if (str != NULL) { + assert(len >= offset); + offset += unibi_run(str, tui->params, buf + offset, len - offset); + } + + return offset; +} + static void flush_buf(TUIData *tui) { uv_write_t req; - uv_buf_t buf; + uv_buf_t bufs[3]; + char pre[32]; + char post[32]; if (tui->bufpos <= 0) { return; } - buf.base = tui->buf; - buf.len = UV_BUF_LEN(tui->bufpos); + bufs[0].base = pre; + bufs[0].len = UV_BUF_LEN(flush_buf_start(tui, pre, sizeof(pre))); + + bufs[1].base = tui->buf; + bufs[1].len = UV_BUF_LEN(tui->bufpos); + + bufs[2].base = post; + bufs[2].len = UV_BUF_LEN(flush_buf_end(tui, post, sizeof(post))); if (tui->screenshot) { - fwrite(buf.base, buf.len, 1, tui->screenshot); + for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) { + fwrite(bufs[i].base, bufs[i].len, 1, tui->screenshot); + } } else { int ret - = uv_write(&req, (uv_stream_t *)&tui->output_handle, &buf, 1, NULL); + = uv_write(&req, (uv_stream_t *)&tui->output_handle, bufs, ARRAY_SIZE(bufs), NULL); if (ret) { ELOG("uv_write failed: %s", uv_strerror(ret)); } -- cgit From 2ebd328a798778825be61015acd975d8a929dfec Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 9 Dec 2023 11:36:11 +0800 Subject: refactor: format casting of negative number better (#26482) --- src/nvim/eval.c | 2 +- src/nvim/eval/funcs.c | 2 +- src/nvim/lua/converter.c | 2 +- src/nvim/mark.c | 6 +++--- src/nvim/ops.c | 4 ++-- src/nvim/textformat.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 16c1231682..2bbc8b58e7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -5029,7 +5029,7 @@ size_t string2float(const char *const text, float_T *const ret_value) return 3; } if (STRNICMP(text, "-inf", 3) == 0) { - *ret_value = (float_T) - INFINITY; + *ret_value = (float_T)(-INFINITY); return 4; } if (STRNICMP(text, "nan", 3) == 0) { diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 15b81f2f56..b4f0be85e5 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -2171,7 +2171,7 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - if (f <= (float_T) - VARNUMBER_MAX + DBL_EPSILON) { + if (f <= (float_T)(-VARNUMBER_MAX) + DBL_EPSILON) { rettv->vval.v_number = -VARNUMBER_MAX; } else if (f >= (float_T)VARNUMBER_MAX - DBL_EPSILON) { rettv->vval.v_number = VARNUMBER_MAX; diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index ca0be28fac..e26e38f577 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -1254,7 +1254,7 @@ handle_T nlua_pop_handle(lua_State *lstate, Error *err) handle_T ret; if (lua_type(lstate, -1) != LUA_TNUMBER) { api_set_error(err, kErrorTypeValidation, "Expected Lua number"); - ret = (handle_T) - 1; + ret = (handle_T)(-1); } else { ret = (handle_T)lua_tonumber(lstate, -1); } diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 5839cf7a2e..1e2462970f 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1288,12 +1288,12 @@ void mark_adjust_buf(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount if (posp->lnum == lnum && posp->col >= mincol) { \ posp->lnum += lnum_amount; \ assert(col_amount > INT_MIN && col_amount <= INT_MAX); \ - if (col_amount < 0 && posp->col <= (colnr_T) - col_amount) { \ + if (col_amount < 0 && posp->col <= -col_amount) { \ posp->col = 0; \ } else if (posp->col < spaces_removed) { \ - posp->col = (int)col_amount + spaces_removed; \ + posp->col = col_amount + spaces_removed; \ } else { \ - posp->col += (colnr_T)col_amount; \ + posp->col += col_amount; \ } \ } \ } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 3a4e87edf7..16aa46e97d 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -4630,13 +4630,13 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) if (!pre) { if (subtract) { if (n > oldn) { - n = 1 + (n ^ (uvarnumber_T) - 1); + n = 1 + (n ^ (uvarnumber_T)(-1)); negative ^= true; } } else { // add if (n < oldn) { - n = (n ^ (uvarnumber_T) - 1); + n = (n ^ (uvarnumber_T)(-1)); negative ^= true; } } diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 5d7f5b747b..8e52ad660b 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -678,7 +678,7 @@ void auto_format(bool trailblank, bool prev_line) // Do the formatting and restore the cursor position. "saved_cursor" will // be adjusted for the text formatting. saved_cursor = pos; - format_lines((linenr_T) - 1, false); + format_lines(-1, false); curwin->w_cursor = saved_cursor; saved_cursor.lnum = 0; -- cgit From 6346987601a28b00564295ee8be0a8b00d9ff911 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 7 Dec 2023 23:46:57 +0600 Subject: refactor(options): reduce `findoption()` usage Problem: Many places in the code use `findoption()` to access an option using its name, even if the option index is available. This is very slow because it requires looping through the options array over and over. Solution: Use option index instead of name wherever possible. Also introduce an `OptIndex` enum which contains the index for every option as enum constants, this eliminates the need to pass static option names as strings. --- src/nvim/CMakeLists.txt | 5 +- src/nvim/api/deprecated.c | 11 +- src/nvim/api/options.c | 65 ++++----- src/nvim/api/vim.c | 6 +- src/nvim/autocmd.c | 4 +- src/nvim/buffer.c | 10 +- src/nvim/context.c | 6 +- src/nvim/diff.c | 4 +- src/nvim/eval.c | 14 +- src/nvim/eval/funcs.c | 2 +- src/nvim/eval/vars.c | 11 +- src/nvim/ex_cmds.c | 10 +- src/nvim/ex_docmd.c | 6 +- src/nvim/ex_getln.c | 6 +- src/nvim/fileio.c | 4 +- src/nvim/generators/gen_options.lua | 17 +++ src/nvim/help.c | 8 +- src/nvim/highlight_group.c | 7 +- src/nvim/indent.c | 4 +- src/nvim/main.c | 24 ++-- src/nvim/memline.c | 2 +- src/nvim/option.c | 276 ++++++++++++++++-------------------- src/nvim/option.h | 2 +- src/nvim/option_defs.h | 5 + src/nvim/optionstr.c | 83 +++++------ src/nvim/path.c | 2 +- src/nvim/popupmenu.c | 10 +- src/nvim/quickfix.c | 16 +-- src/nvim/runtime.c | 2 +- src/nvim/spell.c | 6 +- src/nvim/spellfile.c | 2 +- src/nvim/statusline.c | 33 +++-- src/nvim/statusline.h | 1 + src/nvim/terminal.c | 6 +- src/nvim/textformat.c | 2 +- src/nvim/ui.c | 2 +- src/nvim/window.c | 2 +- 37 files changed, 330 insertions(+), 346 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 0cdce539eb..95ea55f36d 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -332,6 +332,7 @@ set(GENERATED_KEYSETS_DEFS ${GENERATED_DIR}/keysets_defs.generated.h) set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h) set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h) set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h) +set(GENERATED_OPTIONS_ENUM ${GENERATED_DIR}/options_enum.generated.h) set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua) set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua) set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua) @@ -676,8 +677,8 @@ add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} DEPENDS ${LUA_GEN_DEPS} ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua ) -add_custom_command(OUTPUT ${GENERATED_OPTIONS} - COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} +add_custom_command(OUTPUT ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} + COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua ) diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index d6a76617a7..34bf029483 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -643,7 +643,7 @@ static Object get_option_from(void *from, OptReqScope req_scope, String name, Er return (Object)OBJECT_INIT; }); - OptVal value = get_option_value_strict(name.data, req_scope, from, err); + OptVal value = get_option_value_strict(findoption(name.data), req_scope, from, err); if (ERROR_SET(err)) { return (Object)OBJECT_INIT; } @@ -669,8 +669,8 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, return; }); - int flags = get_option_attrs(name.data); - VALIDATE_S(flags != 0, "option name", name.data, { + int opt_idx = findoption(name.data); + VALIDATE_S(opt_idx >= 0, "option name", name.data, { return; }); @@ -685,13 +685,14 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, return; }); + int attrs = get_option_attrs(opt_idx); // For global-win-local options -> setlocal // For win-local options -> setglobal and setlocal (opt_flags == 0) - const int opt_flags = (req_scope == kOptReqWin && !(flags & SOPT_GLOBAL)) + const int opt_flags = (req_scope == kOptReqWin && !(attrs & SOPT_GLOBAL)) ? 0 : (req_scope == kOptReqGlobal) ? OPT_GLOBAL : OPT_LOCAL; WITH_SCRIPT_CONTEXT(channel_id, { - set_option_value_for(name.data, optval, opt_flags, req_scope, to, err); + set_option_value_for(name.data, opt_idx, optval, opt_flags, req_scope, to, err); }); } diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 53fd8af8b5..0d18c7871c 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -23,7 +23,7 @@ # include "api/options.c.generated.h" #endif -static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, +static int validate_option_value_args(Dict(option) *opts, char *name, int *opt_idx, int *scope, OptReqScope *req_scope, void **from, char **filetype, Error *err) { @@ -79,7 +79,8 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope return FAIL; }); - int flags = get_option_attrs(name); + *opt_idx = findoption(name); + int flags = get_option_attrs(*opt_idx); if (flags == 0) { // hidden or unknown option api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name); @@ -119,10 +120,10 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) aucmd_prepbuf(aco, ftbuf); TRY_WRAP(err, { - set_option_value("bufhidden", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); - set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); - set_option_value("swapfile", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value("modeline", BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline' + set_option_value(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value(kOptModeline, BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline' ftbuf->b_p_ft = xstrdup(filetype); do_filetype_autocmd(ftbuf, false); @@ -152,12 +153,14 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(9) { + int opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; char *filetype = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, &filetype, err)) { + if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &from, &filetype, + err)) { return (Object)OBJECT_INIT; } @@ -173,7 +176,6 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) from = ftbuf; } - int opt_idx = findoption(name.data); OptVal value = get_option_value_for(opt_idx, scope, req_scope, from, err); bool hidden = is_option_hidden(opt_idx); @@ -217,10 +219,11 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( Error *err) FUNC_API_SINCE(9) { + int opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *to = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &to, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &to, NULL, err)) { return; } @@ -231,7 +234,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( // // Then force scope to local since we don't want to change the global option if (req_scope == kOptReqWin && scope == 0) { - int flags = get_option_attrs(name.data); + int flags = get_option_attrs(opt_idx); if (flags & SOPT_GLOBAL) { scope = OPT_LOCAL; } @@ -249,7 +252,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( }); WITH_SCRIPT_CONTEXT(channel_id, { - set_option_value_for(name.data, optval, scope, req_scope, to, err); + set_option_value_for(name.data, opt_idx, optval, scope, req_scope, to, err); }); } @@ -303,10 +306,12 @@ Dictionary nvim_get_all_options_info(Error *err) Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(11) { + int opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &from, NULL, + err)) { return (Dictionary)ARRAY_DICT_INIT; } @@ -382,19 +387,13 @@ static void restore_option_context(void *const ctx, OptReqScope req_scope) /// Get attributes for an option. /// -/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// /// @return Option attributes. /// 0 for hidden or unknown option. /// See SOPT_* in option_defs.h for other flags. -int get_option_attrs(char *name) +int get_option_attrs(int opt_idx) { - if (is_tty_option(name)) { - return SOPT_GLOBAL; - } - - int opt_idx = findoption(name); - if (opt_idx < 0) { return 0; } @@ -422,14 +421,12 @@ int get_option_attrs(char *name) /// Check if option has a value in the requested scope. /// -/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// @param req_scope Requested option scope. See OptReqScope in option.h. /// /// @return true if option has a value in the requested scope, false otherwise. -static bool option_has_scope(char *name, OptReqScope req_scope) +static bool option_has_scope(int opt_idx, OptReqScope req_scope) { - int opt_idx = findoption(name); - if (opt_idx < 0) { return false; } @@ -458,7 +455,7 @@ static bool option_has_scope(char *name, OptReqScope req_scope) /// Get the option value in the requested scope. /// -/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// @param req_scope Requested option scope. See OptReqScope in option.h. /// @param[in] from Pointer to buffer or window for local option value. /// @param[out] err Error message, if any. @@ -466,17 +463,11 @@ static bool option_has_scope(char *name, OptReqScope req_scope) /// @return Option value in the requested scope. Returns a Nil option value if option is not found, /// hidden or if it isn't present in the requested scope. (i.e. has no global, window-local or /// buffer-local value depending on opt_scope). -OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Error *err) +OptVal get_option_value_strict(int opt_idx, OptReqScope req_scope, void *from, Error *err) { - if (!option_has_scope(name, req_scope)) { + if (opt_idx < 0 || !option_has_scope(opt_idx, req_scope)) { return NIL_OPTVAL; } - if (is_tty_option(name)) { - return get_tty_option(name); - } - - int opt_idx = findoption(name); - assert(opt_idx != 0); // option_has_scope() already verifies if option name is valid. vimoption_T *opt = get_option(opt_idx); switchwin_T switchwin; @@ -533,14 +524,16 @@ OptVal get_option_value_for(int opt_idx, int scope, const OptReqScope req_scope, /// Set option value for buffer / window. /// -/// @param[in] name Option name. +/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// @param[in] value Option value. /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). /// @param req_scope Requested option scope. See OptReqScope in option.h. /// @param[in] from Target buffer/window. /// @param[out] err Error message, if any. -void set_option_value_for(const char *const name, OptVal value, const int opt_flags, +void set_option_value_for(const char *name, int opt_idx, OptVal value, const int opt_flags, const OptReqScope req_scope, void *const from, Error *err) + FUNC_ATTR_NONNULL_ARG(1) { switchwin_T switchwin; aco_save_T aco; @@ -552,7 +545,7 @@ void set_option_value_for(const char *const name, OptVal value, const int opt_fl return; } - const char *const errmsg = set_option_value(name, value, opt_flags); + const char *const errmsg = set_option_value_handle_tty(name, opt_idx, value, opt_flags); if (errmsg) { api_set_error(err, kErrorTypeException, "%s", errmsg); } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2c937113e3..a52d7493e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -948,8 +948,8 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) buf_copy_options(buf, BCO_ENTER | BCO_NOHELP); if (scratch) { - set_string_option_direct_in_buf(buf, "bufhidden", -1, "hide", OPT_LOCAL, 0); - set_string_option_direct_in_buf(buf, "buftype", -1, "nofile", OPT_LOCAL, 0); + set_string_option_direct_in_buf(buf, kOptBufhidden, "hide", OPT_LOCAL, 0); + set_string_option_direct_in_buf(buf, kOptBuftype, "nofile", OPT_LOCAL, 0); assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already buf->b_p_swf = false; buf->b_p_ml = false; @@ -2239,7 +2239,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * buf, sizeof(buf), str.data, - NULL, + -1, 0, fillchar, maxwidth, diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 46a08c5706..72b0852d8d 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -704,7 +704,7 @@ char *au_event_disable(char *what) } else { STRCAT(new_ei, what); } - set_string_option_direct("ei", -1, new_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, new_ei, OPT_FREE, SID_NONE); xfree(new_ei); return save_ei; } @@ -712,7 +712,7 @@ char *au_event_disable(char *what) void au_event_restore(char *old_ei) { if (old_ei != NULL) { - set_string_option_direct("ei", -1, old_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, old_ei, OPT_FREE, SID_NONE); xfree(old_ei); } } diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index b5fac15af6..0392ff6ebd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3281,7 +3281,7 @@ void maketitle(void) if (*p_titlestring != NUL) { if (stl_syntax & STL_IN_TITLE) { build_stl_str_hl(curwin, buf, sizeof(buf), p_titlestring, - "titlestring", 0, 0, maxlen, NULL, NULL, NULL); + kOptTitlestring, 0, 0, maxlen, NULL, NULL, NULL); title_str = buf; } else { title_str = p_titlestring; @@ -3386,7 +3386,7 @@ void maketitle(void) if (*p_iconstring != NUL) { if (stl_syntax & STL_IN_ICON) { build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring, - "iconstring", 0, 0, 0, NULL, NULL, NULL); + kOptIconstring, 0, 0, 0, NULL, NULL, NULL); } else { icon_str = p_iconstring; } @@ -4147,9 +4147,9 @@ int buf_open_scratch(handle_T bufnr, char *bufname) apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf); (void)setfname(curbuf, bufname, NULL, true); apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); RESET_BINDING(curwin); return OK; } diff --git a/src/nvim/context.c b/src/nvim/context.c index 63c0f8c20c..dfb214d065 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -138,8 +138,8 @@ bool ctx_restore(Context *ctx, const int flags) free_ctx = true; } - OptVal op_shada = get_option_value(findoption("shada"), OPT_GLOBAL); - set_option_value("shada", STATIC_CSTR_AS_OPTVAL("!,'100,%"), OPT_GLOBAL); + OptVal op_shada = get_option_value(kOptShada, OPT_GLOBAL); + set_option_value(kOptShada, STATIC_CSTR_AS_OPTVAL("!,'100,%"), OPT_GLOBAL); if (flags & kCtxRegs) { ctx_restore_regs(ctx); @@ -165,7 +165,7 @@ bool ctx_restore(Context *ctx, const int flags) ctx_free(ctx); } - set_option_value("shada", op_shada, OPT_GLOBAL); + set_option_value(kOptShada, op_shada, OPT_GLOBAL); optval_free(op_shada); return true; diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 6578a1121c..483182dc25 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1389,7 +1389,7 @@ static void set_diff_option(win_T *wp, bool value) curwin = wp; curbuf = curwin->w_buffer; curbuf->b_ro_locked++; - set_option_value_give_err("diff", BOOLEAN_OPTVAL(value), OPT_LOCAL); + set_option_value_give_err(kOptDiff, BOOLEAN_OPTVAL(value), OPT_LOCAL); curbuf->b_ro_locked--; curwin = old_curwin; curbuf = curwin->w_buffer; @@ -1430,7 +1430,7 @@ void diff_win_options(win_T *wp, int addbuf) } wp->w_p_fdm_save = xstrdup(wp->w_p_fdm); } - set_string_option_direct_in_win(wp, "fdm", -1, "diff", OPT_LOCAL | OPT_FREE, 0); + set_string_option_direct_in_win(wp, kOptFoldmethod, "diff", OPT_LOCAL | OPT_FREE, 0); if (!wp->w_p_diff) { wp->w_p_fen_save = wp->w_p_fen; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2bbc8b58e7..1c30075991 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -681,7 +681,7 @@ int eval_charconvert(const char *const enc_from, const char *const enc_to, set_vim_var_string(VV_CC_TO, enc_to, -1); set_vim_var_string(VV_FNAME_IN, fname_from, -1); set_vim_var_string(VV_FNAME_OUT, fname_to, -1); - sctx_T *ctx = get_option_sctx("charconvert"); + sctx_T *ctx = get_option_sctx(kOptCharconvert); if (ctx != NULL) { current_sctx = *ctx; } @@ -710,7 +710,7 @@ void eval_diff(const char *const origfile, const char *const newfile, const char set_vim_var_string(VV_FNAME_NEW, newfile, -1); set_vim_var_string(VV_FNAME_OUT, outfile, -1); - sctx_T *ctx = get_option_sctx("diffexpr"); + sctx_T *ctx = get_option_sctx(kOptDiffexpr); if (ctx != NULL) { current_sctx = *ctx; } @@ -732,7 +732,7 @@ void eval_patch(const char *const origfile, const char *const difffile, const ch set_vim_var_string(VV_FNAME_DIFF, difffile, -1); set_vim_var_string(VV_FNAME_OUT, outfile, -1); - sctx_T *ctx = get_option_sctx("patchexpr"); + sctx_T *ctx = get_option_sctx(kOptPatchexpr); if (ctx != NULL) { current_sctx = *ctx; } @@ -1134,7 +1134,7 @@ list_T *eval_spell_expr(char *badword, char *expr) if (p_verbose == 0) { emsg_off++; } - sctx_T *ctx = get_option_sctx("spellsuggest"); + sctx_T *ctx = get_option_sctx(kOptSpellsuggest); if (ctx != NULL) { current_sctx = *ctx; } @@ -1278,7 +1278,7 @@ void *call_func_retlist(const char *func, int argc, typval_T *argv) int eval_foldexpr(win_T *wp, int *cp) { const sctx_T saved_sctx = current_sctx; - const bool use_sandbox = was_set_insecurely(wp, "foldexpr", OPT_LOCAL); + const bool use_sandbox = was_set_insecurely(wp, kOptFoldexpr, OPT_LOCAL); char *arg = wp->w_p_fde; current_sctx = wp->w_p_script_ctx[WV_FDE].script_ctx; @@ -1326,7 +1326,7 @@ int eval_foldexpr(win_T *wp, int *cp) /// Evaluate 'foldtext', returning an Array or a String (NULL_STRING on failure). Object eval_foldtext(win_T *wp) { - const bool use_sandbox = was_set_insecurely(wp, "foldtext", OPT_LOCAL); + const bool use_sandbox = was_set_insecurely(wp, kOptFoldtext, OPT_LOCAL); char *arg = wp->w_p_fdt; funccal_entry_T funccal_entry; @@ -8715,7 +8715,7 @@ char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char // If it's still empty it was changed and restored, need to restore in // the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } free_string_option(save_cpo); } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b4f0be85e5..c35e0b2ada 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -7239,7 +7239,7 @@ int do_searchpair(const char *spat, const char *mpat, const char *epat, int dir, // If it's still empty it was changed and restored, need to restore in // the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } free_string_option(save_cpo); } diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 8864edbf69..9b7a61f969 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -834,7 +834,7 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, } } - const char *err = set_option_value(arg, newval, scope); + const char *err = set_option_value_handle_tty(arg, opt_idx, newval, scope); arg_end = p; if (err != NULL) { emsg(_(err)); @@ -1945,15 +1945,18 @@ static void set_option_from_tv(const char *varname, typval_T *varp) semsg(_(e_unknown_option2), varname); return; } - uint32_t opt_p_flags = get_option(opt_idx)->flags; bool error = false; + uint32_t opt_p_flags = get_option_flags(opt_idx); OptVal value = tv_to_optval(varp, varname, opt_p_flags, &error); if (!error) { - set_option_value_give_err(varname, value, OPT_LOCAL); - } + const char *errmsg = set_option_value_handle_tty(varname, opt_idx, value, OPT_LOCAL); + if (errmsg) { + emsg(errmsg); + } + } optval_free(value); } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 68c316fde0..786612070e 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4265,7 +4265,7 @@ skip: // Show 'inccommand' preview if there are matched lines. if (cmdpreview_ns > 0 && !aborting()) { if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable. - set_string_option_direct("icm", -1, "", OPT_FREE, SID_NONE); + set_string_option_direct(kOptInccommand, "", OPT_FREE, SID_NONE); } else if (*p_icm != NUL && pat != NULL) { if (pre_hl_id == 0) { pre_hl_id = syn_check_group(S_LEN("Substitute")); @@ -4544,8 +4544,8 @@ bool prepare_tagpreview(bool undo_sync) curwin->w_p_wfh = true; RESET_BINDING(curwin); // don't take over 'scrollbind' and 'cursorbind' curwin->w_p_diff = false; // no 'diff' - set_string_option_direct("fdc", -1, // no 'foldcolumn' - "0", OPT_FREE, SID_NONE); + + set_string_option_direct(kOptFoldcolumn, "0", OPT_FREE, SID_NONE); // no 'foldcolumn' return true; } @@ -4564,7 +4564,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i buf_T *cmdpreview_buf = NULL; // disable file info message - set_string_option_direct("shm", -1, "F", OPT_FREE, SID_NONE); + set_string_option_direct(kOptShortmess, "F", OPT_FREE, SID_NONE); // Update the topline to ensure that main window is on the correct line update_topline(curwin); @@ -4665,7 +4665,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i xfree(str); - set_string_option_direct("shm", -1, save_shm_p, OPT_FREE, SID_NONE); + set_string_option_direct(kOptShortmess, save_shm_p, OPT_FREE, SID_NONE); xfree(save_shm_p); return preview ? 2 : 1; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 90b816bb6f..ff80ee9e54 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2653,7 +2653,7 @@ static void apply_cmdmod(cmdmod_T *cmod) // Set 'eventignore' to "all". // First save the existing option value for restoring it later. cmod->cmod_save_ei = xstrdup(p_ei); - set_string_option_direct("ei", -1, "all", OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, "all", OPT_FREE, SID_NONE); } } @@ -2673,7 +2673,7 @@ void undo_cmdmod(cmdmod_T *cmod) if (cmod->cmod_save_ei != NULL) { // Restore 'eventignore' to the value before ":noautocmd". - set_string_option_direct("ei", -1, cmod->cmod_save_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, cmod->cmod_save_ei, OPT_FREE, SID_NONE); free_string_option(cmod->cmod_save_ei); cmod->cmod_save_ei = NULL; } @@ -7306,7 +7306,7 @@ static void ex_setfiletype(exarg_T *eap) arg += 9; } - set_option_value_give_err("filetype", CSTR_AS_OPTVAL(arg), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, CSTR_AS_OPTVAL(arg), OPT_LOCAL); if (arg != eap->arg) { did_filetype = false; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 14d230331a..afaf0a6e2b 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -905,7 +905,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear need_wait_return = false; } - set_string_option_direct("icm", -1, s->save_p_icm, OPT_FREE, SID_NONE); + set_string_option_direct(kOptInccommand, s->save_p_icm, OPT_FREE, SID_NONE); State = s->save_State; if (cmdpreview != save_cmdpreview) { cmdpreview = save_cmdpreview; // restore preview state @@ -4326,7 +4326,7 @@ static int open_cmdwin(void) return Ctrl_C; } // Command-line buffer has bufhidden=wipe, unlike a true "scratch" buffer. - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); curbuf->b_p_ma = true; curwin->w_p_fen = false; curwin->w_p_rl = cmdmsg_rl; @@ -4344,7 +4344,7 @@ static int open_cmdwin(void) add_map("", "", MODE_INSERT, true); add_map("", "a", MODE_NORMAL, true); } - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("vim"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("vim"), OPT_LOCAL); } curbuf->b_ro_locked--; diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 4fe5b1cd44..0e2959835b 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1617,7 +1617,7 @@ failed: save_file_ff(curbuf); // If editing a new file: set 'fenc' for the current buffer. // Also for ":read ++edit file". - set_string_option_direct("fenc", -1, fenc, OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct(kOptFileencoding, fenc, OPT_FREE | OPT_LOCAL, 0); } if (fenc_alloced) { xfree(fenc); @@ -1965,7 +1965,7 @@ void set_forced_fenc(exarg_T *eap) } char *fenc = enc_canonize(eap->cmd + eap->force_enc); - set_string_option_direct("fenc", -1, fenc, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptFileencoding, fenc, OPT_FREE|OPT_LOCAL, 0); xfree(fenc); } diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 3a355634f3..2b17add7ba 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -1,4 +1,5 @@ local options_file = arg[1] +local options_enum_file = arg[2] local opt_fd = assert(io.open(options_file, 'w')) @@ -41,6 +42,12 @@ local list_flags = { flagscomma = 'P_COMMA|P_FLAGLIST', } +--- @param s string +--- @return string +local title_case = function(s) + return s:sub(1, 1):upper() .. s:sub(2):lower() +end + --- @param o vim.option_meta --- @return string local function get_flags(o) @@ -229,4 +236,14 @@ w('') for _, v in ipairs(defines) do w('#define ' .. v[1] .. ' ' .. v[2]) end + +-- Generate options enum file +opt_fd = assert(io.open(options_enum_file, 'w')) + +w('typedef enum {') +for i, o in ipairs(options.options) do + w((' kOpt%s = %u,'):format(title_case(o.full_name), i - 1)) +end +w('} OptIndex;') + opt_fd:close() diff --git a/src/nvim/help.c b/src/nvim/help.c index dc4f6c44ff..28b95b2346 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -608,7 +608,7 @@ void cleanup_help_tags(int num_file, char **file) void prepare_help_buffer(void) { curbuf->b_help = true; - set_string_option_direct("buftype", -1, "help", OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptBuftype, "help", OPT_FREE|OPT_LOCAL, 0); // Always set these options after jumping to a help tag, because the // user may have an autocommand that gets in the way. @@ -617,13 +617,13 @@ void prepare_help_buffer(void) // Only set it when needed, buf_init_chartab() is some work. char *p = "!-~,^*,^|,^\",192-255"; if (strcmp(curbuf->b_p_isk, p) != 0) { - set_string_option_direct("isk", -1, p, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptIskeyword, p, OPT_FREE|OPT_LOCAL, 0); check_buf_options(curbuf); (void)buf_init_chartab(curbuf, false); } // Don't use the global foldmethod. - set_string_option_direct("fdm", -1, "manual", OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptFoldmethod, "manual", OPT_FREE|OPT_LOCAL, 0); curbuf->b_p_ts = 8; // 'tabstop' is 8. curwin->w_p_list = false; // No list mode. @@ -649,7 +649,7 @@ void fix_help_buffer(void) // Set filetype to "help". if (strcmp(curbuf->b_p_ft, "help") != 0) { curbuf->b_ro_locked++; - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("help"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("help"), OPT_LOCAL); curbuf->b_ro_locked--; } diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 3bd4aa4f64..4add1e3591 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -1337,9 +1337,10 @@ void do_highlight(const char *line, const bool forceit, const bool init) // wrong. if (dark != -1 && dark != (*p_bg == 'd') - && !option_was_set("bg")) { - set_option_value_give_err("bg", CSTR_AS_OPTVAL(dark ? "dark" : "light"), 0); - reset_option_was_set("bg"); + && !option_was_set(kOptBackground)) { + set_option_value_give_err(kOptBackground, + CSTR_AS_OPTVAL(dark ? "dark" : "light"), 0); + reset_option_was_set(kOptBackground); } } } diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 5dced37b40..925317e7cb 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -1091,7 +1091,7 @@ void ex_retab(exarg_T *eap) colnr_T *old_vts_ary = curbuf->b_p_vts_array; if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) { - set_string_option_direct("vts", -1, new_ts_str, OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct(kOptVartabstop, new_ts_str, OPT_FREE | OPT_LOCAL, 0); curbuf->b_p_vts_array = new_vts_array; xfree(old_vts_ary); } else { @@ -1115,7 +1115,7 @@ int get_expr_indent(void) colnr_T save_curswant; int save_set_curswant; int save_State; - int use_sandbox = was_set_insecurely(curwin, "indentexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, kOptIndentexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Save and restore cursor position and curswant, in case it was changed diff --git a/src/nvim/main.c b/src/nvim/main.c index 216e39f3e8..521d67a638 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1123,7 +1123,7 @@ static void command_line_scan(mparm_T *parmp) } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { parmp->use_vimrc = "NONE"; parmp->clean = true; - set_option_value_give_err("shadafile", STATIC_CSTR_AS_OPTVAL("NONE"), 0); + set_option_value_give_err(kOptShadafile, STATIC_CSTR_AS_OPTVAL("NONE"), 0); } else if (STRNICMP(argv[0] + argv_idx, "luamod-dev", 9) == 0) { nlua_disable_preload = true; } else { @@ -1137,7 +1137,7 @@ static void command_line_scan(mparm_T *parmp) } break; case 'A': // "-A" start in Arabic mode. - set_option_value_give_err("arabic", BOOLEAN_OPTVAL(true), 0); + set_option_value_give_err(kOptArabic, BOOLEAN_OPTVAL(true), 0); break; case 'b': // "-b" binary mode. // Needs to be effective before expanding file names, because @@ -1167,8 +1167,8 @@ static void command_line_scan(mparm_T *parmp) usage(); os_exit(0); case 'H': // "-H" start in Hebrew mode: rl + keymap=hebrew set. - set_option_value_give_err("keymap", STATIC_CSTR_AS_OPTVAL("hebrew"), 0); - set_option_value_give_err("rl", BOOLEAN_OPTVAL(true), 0); + set_option_value_give_err(kOptKeymap, STATIC_CSTR_AS_OPTVAL("hebrew"), 0); + set_option_value_give_err(kOptRightleft, BOOLEAN_OPTVAL(true), 0); break; case 'M': // "-M" no changes or writing of files reset_modifiable(); @@ -1248,7 +1248,7 @@ static void command_line_scan(mparm_T *parmp) // default is 10: a little bit verbose p_verbose = get_number_arg(argv[0], &argv_idx, 10); if (argv[0][argv_idx] != NUL) { - set_option_value_give_err("verbosefile", CSTR_AS_OPTVAL(argv[0] + argv_idx), 0); + set_option_value_give_err(kOptVerbosefile, CSTR_AS_OPTVAL(argv[0] + argv_idx), 0); argv_idx = (int)strlen(argv[0]); } break; @@ -1256,7 +1256,7 @@ static void command_line_scan(mparm_T *parmp) // "-w {scriptout}" write to script if (ascii_isdigit((argv[0])[argv_idx])) { n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value_give_err("window", NUMBER_OPTVAL((OptInt)n), 0); + set_option_value_give_err(kOptWindow, NUMBER_OPTVAL((OptInt)n), 0); break; } want_argument = true; @@ -1352,7 +1352,7 @@ static void command_line_scan(mparm_T *parmp) break; case 'i': // "-i {shada}" use for shada - set_option_value_give_err("shadafile", CSTR_AS_OPTVAL(argv[0]), 0); + set_option_value_give_err(kOptShadafile, CSTR_AS_OPTVAL(argv[0]), 0); break; case 'l': // "-l" Lua script: args after "-l". @@ -1362,7 +1362,7 @@ static void command_line_scan(mparm_T *parmp) parmp->no_swap_file = true; parmp->use_vimrc = parmp->use_vimrc ? parmp->use_vimrc : "NONE"; if (p_shadafile == NULL || *p_shadafile == NUL) { - set_option_value_give_err("shadafile", STATIC_CSTR_AS_OPTVAL("NONE"), 0); + set_option_value_give_err(kOptShadafile, STATIC_CSTR_AS_OPTVAL("NONE"), 0); } parmp->luaf = argv[0]; argc--; @@ -1398,7 +1398,7 @@ scripterror: if (ascii_isdigit(*(argv[0]))) { argv_idx = 0; n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value_give_err("window", NUMBER_OPTVAL((OptInt)n), 0); + set_option_value_give_err(kOptWindow, NUMBER_OPTVAL((OptInt)n), 0); argv_idx = -1; break; } @@ -1549,7 +1549,7 @@ static void handle_quickfix(mparm_T *paramp) { if (paramp->edit_type == EDIT_QF) { if (paramp->use_ef != NULL) { - set_string_option_direct("ef", -1, paramp->use_ef, OPT_FREE, SID_CARG); + set_string_option_direct(kOptErrorfile, paramp->use_ef, OPT_FREE, SID_CARG); } vim_snprintf(IObuff, IOSIZE, "cfile %s", p_ef); if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) { @@ -1794,7 +1794,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd) p_shm_save = xstrdup(p_shm); snprintf(buf, sizeof(buf), "F%s", p_shm); - set_option_value_give_err("shm", CSTR_AS_OPTVAL(buf), 0); + set_option_value_give_err(kOptShortmess, CSTR_AS_OPTVAL(buf), 0); } } else { if (curwin->w_next == NULL) { // just checking @@ -1839,7 +1839,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd) } if (p_shm_save != NULL) { - set_option_value_give_err("shm", CSTR_AS_OPTVAL(p_shm_save), 0); + set_option_value_give_err(kOptShortmess, CSTR_AS_OPTVAL(p_shm_save), 0); xfree(p_shm_save); } diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 5e768839ba..9dc2d929b2 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -974,7 +974,7 @@ void ml_recover(bool checkext) set_fileformat(b0_ff - 1, OPT_LOCAL); } if (b0_fenc != NULL) { - set_option_value_give_err("fenc", CSTR_AS_OPTVAL(b0_fenc), OPT_LOCAL); + set_option_value_give_err(kOptFileencoding, CSTR_AS_OPTVAL(b0_fenc), OPT_LOCAL); xfree(b0_fenc); } unchanged(curbuf, true, true); diff --git a/src/nvim/option.c b/src/nvim/option.c index b5291f616b..71d9a2800c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -156,19 +156,19 @@ typedef enum { # include "options.generated.h" #endif -static char *(p_bin_dep_opts[]) = { - "textwidth", "wrapmargin", "modeline", "expandtab", NULL +static int p_bin_dep_opts[] = { + kOptTextwidth, kOptWrapmargin, kOptModeline, kOptExpandtab, -1 }; -static char *(p_paste_dep_opts[]) = { - "autoindent", "expandtab", "ruler", "showmatch", "smarttab", - "softtabstop", "textwidth", "wrapmargin", "revins", "varsofttabstop", NULL + +static int p_paste_dep_opts[] = { + kOptAutoindent, kOptExpandtab, kOptRuler, kOptShowmatch, kOptSmarttab, + kOptSofttabstop, kOptTextwidth, kOptWrapmargin, kOptRevins, kOptVarsofttabstop, -1 }; void set_init_tablocal(void) { // susy baka: cmdheight calls itself OPT_GLOBAL but is really tablocal! - int ch_idx = findoption("cmdheight"); - p_ch = (OptInt)(intptr_t)options[ch_idx].def_val; + p_ch = (OptInt)(intptr_t)options[kOptCmdheight].def_val; } /// Initialize the 'shell' option to a default value. @@ -182,9 +182,9 @@ static void set_init_default_shell(void) const size_t len = strlen(shell) + 3; // two quotes and a trailing NUL char *const cmd = xmalloc(len); snprintf(cmd, len, "\"%s\"", shell); - set_string_default("sh", cmd, true); + set_string_default(kOptShell, cmd, true); } else { - set_string_default("sh", (char *)shell, false); + set_string_default(kOptShell, (char *)shell, false); } } } @@ -199,7 +199,7 @@ static void set_init_default_backupskip(void) static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" }; #endif garray_T ga; - int opt_idx = findoption("backupskip"); + int opt_idx = kOptBackupskip; ga_init(&ga, 1, 100); for (size_t n = 0; n < ARRAY_SIZE(names); n++) { @@ -243,7 +243,7 @@ static void set_init_default_backupskip(void) } } if (ga.ga_data != NULL) { - set_string_default("bsk", ga.ga_data, true); + set_string_default(kOptBackupskip, ga.ga_data, true); } } @@ -269,7 +269,7 @@ static void set_init_default_cdpath(void) } } buf[j] = NUL; - int opt_idx = findoption("cdpath"); + int opt_idx = kOptCdpath; if (opt_idx >= 0) { options[opt_idx].def_val = buf; options[opt_idx].flags |= P_DEF_ALLOCED; @@ -346,20 +346,20 @@ void set_init_1(bool clean_arg) backupdir = xrealloc(backupdir, backupdir_len + 3); memmove(backupdir + 2, backupdir, backupdir_len + 1); memmove(backupdir, ".,", 2); - set_string_default("backupdir", backupdir, true); - set_string_default("viewdir", stdpaths_user_state_subpath("view", 2, true), + set_string_default(kOptBackupdir, backupdir, true); + set_string_default(kOptViewdir, stdpaths_user_state_subpath("view", 2, true), true); - set_string_default("directory", stdpaths_user_state_subpath("swap", 2, true), + set_string_default(kOptDirectory, stdpaths_user_state_subpath("swap", 2, true), true); - set_string_default("undodir", stdpaths_user_state_subpath("undo", 2, true), + set_string_default(kOptUndodir, stdpaths_user_state_subpath("undo", 2, true), true); // Set default for &runtimepath. All necessary expansions are performed in // this function. char *rtp = runtimepath_default(clean_arg); if (rtp) { - set_string_default("runtimepath", rtp, true); + set_string_default(kOptRuntimepath, rtp, true); // Make a copy of 'rtp' for 'packpath' - set_string_default("packpath", rtp, false); + set_string_default(kOptPackpath, rtp, false); rtp = NULL; // ownership taken } @@ -398,7 +398,7 @@ void set_init_1(bool clean_arg) // NOTE: mlterm's author is being asked to 'set' a variable // instead of an environment variable due to inheritance. if (os_env_exists("MLTERM")) { - set_option_value_give_err("tbidi", BOOLEAN_OPTVAL(true), 0); + set_option_value_give_err(kOptTermbidi, BOOLEAN_OPTVAL(true), 0); } didset_options2(); @@ -430,10 +430,10 @@ static void set_option_default(const int opt_idx, int opt_flags) uint32_t flags = opt->flags; if (varp != NULL) { // skip hidden option, nothing to do for it if (flags & P_STRING) { - // Use set_string_option_direct() for local options to handle - // freeing and allocating the value. + // Use set_string_option_direct() for local options to handle freeing and allocating the + // value. if (opt->indir != PV_NONE) { - set_string_option_direct(NULL, opt_idx, opt->def_val, opt_flags, 0); + set_string_option_direct(opt_idx, opt->def_val, opt_flags, 0); } else { if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) { free_string_option(*(char **)(varp)); @@ -479,7 +479,7 @@ static void set_option_default(const int opt_idx, int opt_flags) *flagsp = *flagsp & ~P_INSECURE; } - set_option_sctx_idx(opt_idx, opt_flags, current_sctx); + set_option_sctx(opt_idx, opt_flags, current_sctx); } /// Set all options (except terminal options) to their default value. @@ -504,22 +504,23 @@ static void set_options_default(int opt_flags) /// Set the Vi-default value of a string option. /// Used for 'sh', 'backupskip' and 'term'. /// -/// @param name The name of the option -/// @param val The value of the option -/// @param allocated If true, do not copy default as it was already allocated. -static void set_string_default(const char *name, char *val, bool allocated) +/// @param opt_idx Option index in options[] table. +/// @param val The value of the option. +/// @param allocated If true, do not copy default as it was already allocated. +static void set_string_default(int opt_idx, char *val, bool allocated) FUNC_ATTR_NONNULL_ALL { - int opt_idx = findoption(name); - if (opt_idx >= 0) { - vimoption_T *opt = &options[opt_idx]; - if (opt->flags & P_DEF_ALLOCED) { - xfree(opt->def_val); - } + if (opt_idx < 0) { + return; + } - opt->def_val = allocated ? val : xstrdup(val); - opt->flags |= P_DEF_ALLOCED; + vimoption_T *opt = &options[opt_idx]; + if (opt->flags & P_DEF_ALLOCED) { + xfree(opt->def_val); } + + opt->def_val = allocated ? val : xstrdup(val); + opt->flags |= P_DEF_ALLOCED; } /// For an option value that contains comma separated items, find "newval" in @@ -555,9 +556,8 @@ static char *find_dup_item(char *origval, const char *newval, uint32_t flags) /// Set the Vi-default value of a number option. /// Used for 'lines' and 'columns'. -void set_number_default(char *name, OptInt val) +void set_number_default(int opt_idx, OptInt val) { - int opt_idx = findoption(name); if (opt_idx >= 0) { options[opt_idx].def_val = (void *)(intptr_t)val; } @@ -597,18 +597,17 @@ void set_init_2(bool headless) // 'scroll' defaults to half the window height. The stored default is zero, // which results in the actual value computed from the window height. - int idx = findoption("scroll"); - if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) { - set_option_default(idx, OPT_LOCAL); + if (!(options[kOptScroll].flags & P_WAS_SET)) { + set_option_default(kOptScroll, OPT_LOCAL); } comp_col(); // 'window' is only for backwards compatibility with Vi. // Default is Rows - 1. - if (!option_was_set("window")) { + if (!option_was_set(kOptWindow)) { p_window = Rows - 1; } - set_number_default("window", Rows - 1); + set_number_default(kOptWindow, Rows - 1); } /// Initialize the options, part three: After reading the .vimrc @@ -619,14 +618,8 @@ void set_init_3(void) // Set 'shellpipe' and 'shellredir', depending on the 'shell' option. // This is done after other initializations, where 'shell' might have been // set, but only if they have not been set before. - int idx_srr = findoption("srr"); - int do_srr = (idx_srr < 0) - ? false - : !(options[idx_srr].flags & P_WAS_SET); - int idx_sp = findoption("sp"); - int do_sp = (idx_sp < 0) - ? false - : !(options[idx_sp].flags & P_WAS_SET); + int do_srr = !(options[kOptShellredir].flags & P_WAS_SET); + int do_sp = !(options[kOptShellpipe].flags & P_WAS_SET); size_t len = 0; char *p = (char *)invocation_path_tail(p_sh, &len); @@ -641,11 +634,11 @@ void set_init_3(void) || path_fnamecmp(p, "tcsh") == 0) { if (do_sp) { p_sp = "|& tee"; - options[idx_sp].def_val = p_sp; + options[kOptShellpipe].def_val = p_sp; } if (do_srr) { p_srr = ">&"; - options[idx_srr].def_val = p_srr; + options[kOptShellredir].def_val = p_srr; } } else if (path_fnamecmp(p, "sh") == 0 || path_fnamecmp(p, "ksh") == 0 @@ -660,11 +653,11 @@ void set_init_3(void) // Always use POSIX shell style redirection if we reach this if (do_sp) { p_sp = "2>&1| tee"; - options[idx_sp].def_val = p_sp; + options[kOptShellpipe].def_val = p_sp; } if (do_srr) { p_srr = ">%s 2>&1"; - options[idx_srr].def_val = p_srr; + options[kOptShellredir].def_val = p_srr; } } xfree(p); @@ -694,12 +687,11 @@ void set_helplang_default(const char *lang) if (lang_len < 2) { // safety check return; } - int idx = findoption("hlg"); - if (idx < 0 || (options[idx].flags & P_WAS_SET)) { + if (options[kOptHelplang].flags & P_WAS_SET) { return; } - if (options[idx].flags & P_ALLOCED) { + if (options[kOptHelplang].flags & P_ALLOCED) { free_string_option(p_hlg); } p_hlg = xmemdupz(lang, lang_len); @@ -713,7 +705,7 @@ void set_helplang_default(const char *lang) p_hlg[1] = 'n'; } p_hlg[2] = NUL; - options[idx].flags |= P_ALLOCED; + options[kOptHelplang].flags |= P_ALLOCED; } /// 'title' and 'icon' only default to true if they have not been set or reset @@ -726,14 +718,12 @@ void set_title_defaults(void) // If GUI is (going to be) used, we can always set the window title and // icon name. Saves a bit of time, because the X11 display server does // not need to be contacted. - int idx1 = findoption("title"); - if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { - options[idx1].def_val = 0; + if (!(options[kOptTitle].flags & P_WAS_SET)) { + options[kOptTitle].def_val = 0; p_title = 0; } - idx1 = findoption("icon"); - if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { - options[idx1].def_val = 0; + if (!(options[kOptIcon].flags & P_WAS_SET)) { + options[kOptIcon].def_val = 0; p_icon = 0; } } @@ -775,8 +765,7 @@ static char *stropt_get_default_val(int opt_idx, uint64_t flags) } /// Copy the new string value into allocated memory for the option. -/// Can't use set_string_option_direct(), because we need to remove the -/// backslashes. +/// Can't use set_string_option_direct(), because we need to remove the backslashes. static char *stropt_copy_value(char *origval, char **argp, set_op_T op, uint32_t flags FUNC_ATTR_UNUSED) { @@ -1707,19 +1696,19 @@ void check_options(void) } } -/// Return true when option "opt" was set from a modeline or in secure mode. -/// Return false when it wasn't. -/// Return -1 for an unknown option. -int was_set_insecurely(win_T *const wp, char *opt, int opt_flags) +/// Check if option was set insecurely. +/// +/// @param wp Window. +/// @param opt_idx Option index in options[] table. +/// @param opt_flags Option flags. +/// +/// @return True if option was set from a modeline or in secure mode, false if it wasn't. +int was_set_insecurely(win_T *const wp, int opt_idx, int opt_flags) { - int idx = findoption(opt); + assert(opt_idx >= 0); - if (idx >= 0) { - uint32_t *flagp = insecure_flag(wp, idx, opt_flags); - return (*flagp & P_INSECURE) != 0; - } - internal_error("was_set_insecurely()"); - return -1; + uint32_t *flagp = insecure_flag(wp, opt_idx, opt_flags); + return (*flagp & P_INSECURE) != 0; } /// Get a pointer to the flags used for the P_INSECURE flag of option @@ -1829,21 +1818,16 @@ bool parse_winhl_opt(win_T *wp) return true; } -/// Get the script context of global option "name". -sctx_T *get_option_sctx(const char *const name) +/// Get the script context of global option at index opt_idx. +sctx_T *get_option_sctx(int opt_idx) { - int idx = findoption(name); - - if (idx >= 0) { - return &options[idx].last_set.script_ctx; - } - siemsg("no such option: %s", name); - return NULL; + assert(opt_idx >= 0); + return &options[opt_idx].last_set.script_ctx; } /// Set the script_ctx for an option, taking care of setting the buffer- or /// window-local value. -void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx) +void set_option_sctx(int opt_idx, int opt_flags, sctx_T script_ctx) { int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; int indir = (int)options[opt_idx].indir; @@ -1952,7 +1936,7 @@ static const char *did_set_arabic(optset_T *args) p_deco = true; // Force-set the necessary keymap for arabic. - errmsg = set_option_value("keymap", STATIC_CSTR_AS_OPTVAL("arabic"), OPT_LOCAL); + errmsg = set_option_value(kOptKeymap, STATIC_CSTR_AS_OPTVAL("arabic"), OPT_LOCAL); } else { // 'arabic' is reset, handle various sub-settings. if (!p_tbidi) { @@ -2809,7 +2793,7 @@ static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, char *e cmdline_row = new_row; } } - if (p_window >= Rows || !option_was_set("window")) { + if (p_window >= Rows || !option_was_set(kOptWindow)) { p_window = Rows - 1; } } @@ -3590,7 +3574,7 @@ static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, Opt new_value = optval_from_varp(opt_idx, varp); // Remember where the option was set. - set_option_sctx_idx(opt_idx, opt_flags, current_sctx); + set_option_sctx(opt_idx, opt_flags, current_sctx); // Free options that are in allocated memory. // Use "free_oldval", because recursiveness may change the flags (esp. init_highlight()). if (free_oldval) { @@ -3810,29 +3794,20 @@ err: return errmsg; } -/// Set the value of an option +/// Set the value of an option. /// -/// @param[in] name Option name. +/// @param opt_idx Index in options[] table. Must be >= 0. /// @param[in] value Option value. If NIL_OPTVAL, the option value is cleared. /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). /// /// @return NULL on success, an untranslated error message on error. -const char *set_option_value(const char *const name, const OptVal value, int opt_flags) - FUNC_ATTR_NONNULL_ARG(1) +const char *set_option_value(const int opt_idx, const OptVal value, int opt_flags) { - static char errbuf[IOSIZE]; - - if (is_tty_option(name)) { - return NULL; // Fail silently; many old vimrcs set t_xx options. - } - - int opt_idx = findoption(name); - if (opt_idx < 0) { - snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name); - return errbuf; - } + assert(opt_idx >= 0); + static char errbuf[IOSIZE]; uint32_t flags = options[opt_idx].flags; + // Disallow changing some options in the sandbox if (sandbox > 0 && (flags & P_SECURE)) { return _(e_sandbox); @@ -3844,31 +3819,51 @@ const char *set_option_value(const char *const name, const OptVal value, int opt return NULL; } - const char *errmsg = NULL; + return set_option(opt_idx, varp, optval_copy(value), opt_flags, true, errbuf, sizeof(errbuf)); +} - errmsg = set_option(opt_idx, varp, optval_copy(value), opt_flags, true, errbuf, sizeof(errbuf)); +/// Set the value of an option. Supports TTY options, unlike set_option_value(). +/// +/// @param name Option name. Used for error messages and for setting TTY options. +/// @param opt_idx Option indx in options[] table. If less than zero, `name` is used to +/// check if the option is a TTY option, and an error is shown if it's not. +/// If the option is a TTY option, the function fails silently. +/// @param value Option value. If NIL_OPTVAL, the option value is cleared. +/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). +/// +/// @return NULL on success, an untranslated error message on error. +const char *set_option_value_handle_tty(const char *name, int opt_idx, const OptVal value, + int opt_flags) + FUNC_ATTR_NONNULL_ARG(1) +{ + static char errbuf[IOSIZE]; - return errmsg; + if (opt_idx < 0) { + if (is_tty_option(name)) { + return NULL; // Fail silently; many old vimrcs set t_xx options. + } + + snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name); + return errbuf; + } + + return set_option_value(opt_idx, value, opt_flags); } -/// Call set_option_value() and when an error is returned report it. +/// Call set_option_value() and when an error is returned, report it. /// -/// @param opt_flags OPT_LOCAL or 0 (both) -void set_option_value_give_err(const char *name, OptVal value, int opt_flags) +/// @param opt_idx Option index in options[] table. +/// @param value Option value. If NIL_OPTVAL, the option value is cleared. +/// @param opt_flags OPT_LOCAL or 0 (both) +void set_option_value_give_err(const int opt_idx, OptVal value, int opt_flags) { - const char *errmsg = set_option_value(name, value, opt_flags); + const char *errmsg = set_option_value(opt_idx, value, opt_flags); if (errmsg != NULL) { emsg(_(errmsg)); } } -bool is_option_allocated(const char *name) -{ - int idx = findoption(name); - return idx >= 0 && (options[idx].flags & P_ALLOCED); -} - // Translate a string like "t_xx", "" or "" to a key number. // When "has_lt" is true there is a '<' before "*arg_arg". // Returns 0 when the key is not recognized. @@ -5155,14 +5150,9 @@ void buf_copy_options(buf_T *buf, int flags) /// Reset the 'modifiable' option and its default value. void reset_modifiable(void) { - int opt_idx; - curbuf->b_p_ma = false; p_ma = false; - opt_idx = findoption("ma"); - if (opt_idx >= 0) { - options[opt_idx].def_val = false; - } + options[kOptModifiable].def_val = false; } /// Set the global value for 'iminsert' to the local value. @@ -5807,35 +5797,24 @@ void vimrc_found(char *fname, char *envname) } } -/// Check whether global option has been set +/// Check whether global option has been set. /// /// @param[in] name Option name. /// -/// @return True if it was set. -bool option_was_set(const char *name) +/// @return True if option was set. +bool option_was_set(int opt_idx) { - int idx; - - idx = findoption(name); - if (idx < 0) { // Unknown option. - return false; - } else if (options[idx].flags & P_WAS_SET) { - return true; - } - return false; + assert(opt_idx >= 0); + return options[opt_idx].flags & P_WAS_SET; } /// Reset the flag indicating option "name" was set. /// /// @param[in] name Option name. -void reset_option_was_set(const char *name) +void reset_option_was_set(int opt_idx) { - const int idx = findoption(name); - if (idx < 0) { - return; - } - - options[idx].flags &= ~P_WAS_SET; + assert(opt_idx >= 0); + options[opt_idx].flags &= ~P_WAS_SET; } /// fill_culopt_flags() -- called when 'culopt' changes value @@ -5934,17 +5913,14 @@ int option_set_callback_func(char *optval, Callback *optcb) return OK; } -static void didset_options_sctx(int opt_flags, char **buf) +static void didset_options_sctx(int opt_flags, int *buf) { for (int i = 0;; i++) { - if (buf[i] == NULL) { + if (buf[i] == -1) { break; } - int idx = findoption(buf[i]); - if (idx >= 0) { - set_option_sctx_idx(idx, opt_flags, current_sctx); - } + set_option_sctx(buf[i], opt_flags, current_sctx); } } @@ -6084,7 +6060,7 @@ void set_fileformat(int eol_style, int opt_flags) // p is NULL if "eol_style" is EOL_UNKNOWN. if (p != NULL) { - set_string_option_direct("ff", -1, p, OPT_FREE | opt_flags, 0); + set_string_option_direct(kOptFileformat, p, OPT_FREE | opt_flags, 0); } // This may cause the buffer to become (un)modified. diff --git a/src/nvim/option.h b/src/nvim/option.h index 780f359f5d..db438342ab 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -87,7 +87,7 @@ typedef enum { OPT_SKIPRTP = 0x100, ///< "skiprtp" in 'sessionoptions' } OptionFlags; -/// Return value from get_option_value_strict +/// Return value from get_option_attrs(). enum { SOPT_GLOBAL = 0x01, ///< Option has global value SOPT_WIN = 0x02, ///< Option has window-local value diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 6d0401f319..28718c6269 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -122,3 +122,8 @@ typedef enum { kOptReqWin = 1, ///< Request window-local option value kOptReqBuf = 2, ///< Request buffer-local option value } OptReqScope; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +// Initialize the OptIndex enum. +# include "options_enum.generated.h" +#endif diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 64145ba6ac..adb120fc21 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -291,22 +291,9 @@ static void set_string_option_global(vimoption_T *opt, char **varp) /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL. /// /// TODO(famiu): Remove this and its win/buf variants. -void set_string_option_direct(const char *name, int opt_idx, const char *val, int opt_flags, - int set_sid) +void set_string_option_direct(int opt_idx, const char *val, int opt_flags, int set_sid) { - int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; - int idx = opt_idx; - - if (idx == -1) { // Use name. - idx = findoption(name); - if (idx < 0) { // Not found (should not happen). - internal_error("set_string_option_direct()"); - siemsg(_("For option %s"), name); - return; - } - } - - vimoption_T *opt = get_option(idx); + vimoption_T *opt = get_option(opt_idx); if (opt->var == NULL) { // can't set hidden option return; @@ -314,53 +301,53 @@ void set_string_option_direct(const char *name, int opt_idx, const char *val, in assert(opt->var != &p_shada); + int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; char *s = xstrdup(val); - { - char **varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); - if ((opt_flags & OPT_FREE) && (opt->flags & P_ALLOCED)) { - free_string_option(*varp); - } - *varp = s; + char **varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); - // For buffer/window local option may also set the global value. - if (both) { - set_string_option_global(opt, varp); - } + if ((opt_flags & OPT_FREE) && (opt->flags & P_ALLOCED)) { + free_string_option(*varp); + } + *varp = s; - opt->flags |= P_ALLOCED; + // For buffer/window local option may also set the global value. + if (both) { + set_string_option_global(opt, varp); + } - // When setting both values of a global option with a local value, - // make the local value empty, so that the global value is used. - if ((opt->indir & PV_BOTH) && both) { - free_string_option(*varp); - *varp = empty_string_option; - } - if (set_sid != SID_NONE) { - sctx_T script_ctx; + opt->flags |= P_ALLOCED; - if (set_sid == 0) { - script_ctx = current_sctx; - } else { - script_ctx.sc_sid = set_sid; - script_ctx.sc_seq = 0; - script_ctx.sc_lnum = 0; - } - set_option_sctx_idx(idx, opt_flags, script_ctx); + // When setting both values of a global option with a local value, + // make the local value empty, so that the global value is used. + if ((opt->indir & PV_BOTH) && both) { + free_string_option(*varp); + *varp = empty_string_option; + } + if (set_sid != SID_NONE) { + sctx_T script_ctx; + + if (set_sid == 0) { + script_ctx = current_sctx; + } else { + script_ctx.sc_sid = set_sid; + script_ctx.sc_seq = 0; + script_ctx.sc_lnum = 0; } + set_option_sctx(opt_idx, opt_flags, script_ctx); } } /// Like set_string_option_direct(), but for a window-local option in "wp". /// Blocks autocommands to avoid the old curwin becoming invalid. -void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, const char *val, - int opt_flags, int set_sid) +void set_string_option_direct_in_win(win_T *wp, int opt_idx, const char *val, int opt_flags, + int set_sid) { win_T *save_curwin = curwin; block_autocmds(); curwin = wp; curbuf = curwin->w_buffer; - set_string_option_direct(name, opt_idx, val, opt_flags, set_sid); + set_string_option_direct(opt_idx, val, opt_flags, set_sid); curwin = save_curwin; curbuf = curwin->w_buffer; unblock_autocmds(); @@ -368,14 +355,14 @@ void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, c /// Like set_string_option_direct(), but for a buffer-local option in "buf". /// Blocks autocommands to avoid the old curwin becoming invalid. -void set_string_option_direct_in_buf(buf_T *buf, const char *name, int opt_idx, const char *val, - int opt_flags, int set_sid) +void set_string_option_direct_in_buf(buf_T *buf, int opt_idx, const char *val, int opt_flags, + int set_sid) { buf_T *save_curbuf = curbuf; block_autocmds(); curbuf = buf; - set_string_option_direct(name, opt_idx, val, opt_flags, set_sid); + set_string_option_direct(opt_idx, val, opt_flags, set_sid); curbuf = save_curbuf; unblock_autocmds(); } diff --git a/src/nvim/path.c b/src/nvim/path.c index 28de003212..0fc461ae0f 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1666,7 +1666,7 @@ static char *eval_includeexpr(const char *const ptr, const size_t len) current_sctx = curbuf->b_p_script_ctx[BV_INEX].script_ctx; char *res = eval_to_string_safe(curbuf->b_p_inex, - was_set_insecurely(curwin, "includeexpr", OPT_LOCAL)); + was_set_insecurely(curwin, kOptIncludeexpr, OPT_LOCAL)); set_vim_var_string(VV_FNAME, NULL, 0); current_sctx = save_sctx; diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index f009722357..56fc16a82e 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -767,11 +767,11 @@ static bool pum_set_selected(int n, int repeat) if (res == OK) { // Edit a new, empty buffer. Set options for a "wipeout" // buffer. - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bl", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); - set_option_value_give_err("diff", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuflisted, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); + set_option_value_give_err(kOptDiff, BOOLEAN_OPTVAL(false), OPT_LOCAL); } } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 112f9aa35a..976b7e837d 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3645,12 +3645,12 @@ static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsp static void qf_set_cwindow_options(void) { // switch off 'swapfile' - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); RESET_BINDING(curwin); curwin->w_p_diff = false; - set_option_value_give_err("fdm", STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); + set_option_value_give_err(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); } // Open a new quickfix or location list window, load the quickfix buffer and @@ -4212,7 +4212,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q // resembles reading a file into a buffer, it's more logical when using // autocommands. curbuf->b_ro_locked++; - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); curbuf->b_p_ma = false; keep_filetype = true; // don't detect 'filetype' @@ -5090,7 +5090,7 @@ void ex_cfile(exarg_T *eap) } } if (*eap->arg != NUL) { - set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0); + set_string_option_direct(kOptErrorfile, eap->arg, OPT_FREE, 0); } char *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; @@ -7220,7 +7220,7 @@ void ex_helpgrep(exarg_T *eap) bool updated = false; // Make 'cpoptions' empty, the 'l' flag should not be used here. char *const save_cpo = p_cpo; - const bool save_cpo_allocated = is_option_allocated("cpo"); + const bool save_cpo_allocated = (get_option(kOptCpoptions)->flags & P_ALLOCED); p_cpo = empty_string_option; bool new_qi = false; @@ -7258,7 +7258,7 @@ void ex_helpgrep(exarg_T *eap) // Darn, some plugin changed the value. If it's still empty it was // changed and restored, need to restore in the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } if (save_cpo_allocated) { free_string_option(save_cpo); diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 087c26a46f..d0305a1082 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1061,7 +1061,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) xstrlcat(new_rtp, afterdir, new_rtp_capacity); } - set_option_value_give_err("rtp", CSTR_AS_OPTVAL(new_rtp), 0); + set_option_value_give_err(kOptRuntimepath, CSTR_AS_OPTVAL(new_rtp), 0); xfree(new_rtp); retval = OK; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index eb3bcec3ec..d20d113d9c 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3218,14 +3218,14 @@ void ex_spelldump(exarg_T *eap) if (no_spell_checking(curwin)) { return; } - OptVal spl = get_option_value(findoption("spl"), OPT_LOCAL); + OptVal spl = get_option_value(kOptSpelllang, OPT_LOCAL); // Create a new empty buffer in a new window. do_cmdline_cmd("new"); // enable spelling locally in the new window - set_option_value_give_err("spell", BOOLEAN_OPTVAL(true), OPT_LOCAL); - set_option_value_give_err("spl", spl, OPT_LOCAL); + set_option_value_give_err(kOptSpell, BOOLEAN_OPTVAL(true), OPT_LOCAL); + set_option_value_give_err(kOptSpelllang, spl, OPT_LOCAL); optval_free(spl); if (!buf_is_empty(curbuf)) { diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 4aa0508329..027013c5f0 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -5600,7 +5600,7 @@ static void init_spellfile(void) && strstr(path_tail(fname), ".ascii.") != NULL) ? "ascii" : spell_enc())); - set_option_value_give_err("spellfile", CSTR_AS_OPTVAL(buf), OPT_LOCAL); + set_option_value_give_err(kOptSpellfile, CSTR_AS_OPTVAL(buf), OPT_LOCAL); break; } aspath = false; diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 4dac1b1451..87409bb5db 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -296,7 +296,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) char buf[MAXPATHL]; char transbuf[MAXPATHL]; char *stl; - char *opt_name; + int opt_idx = -1; int opt_scope = 0; stl_hlrec_t *hltab; StlClickRecord *tabtab; @@ -320,9 +320,9 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) fillchar = ' '; attr = HL_ATTR(HLF_TPF); maxwidth = Columns; - opt_name = "tabline"; + opt_idx = kOptTabline; } else if (draw_winbar) { - opt_name = "winbar"; + opt_idx = kOptWinbar; stl = ((*wp->w_p_wbr != NUL) ? wp->w_p_wbr : p_wbr); opt_scope = ((*wp->w_p_wbr != NUL) ? OPT_LOCAL : 0); row = -1; // row zero is first row of text @@ -351,7 +351,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) if (draw_ruler) { stl = p_ruf; - opt_name = "rulerformat"; + opt_idx = kOptRulerformat; // advance past any leading group spec - implicit in ru_col if (*stl == '%') { if (*++stl == '-') { @@ -379,7 +379,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) attr = HL_ATTR(HLF_MSG); } } else { - opt_name = "statusline"; + opt_idx = kOptStatusline; stl = ((*wp->w_p_stl != NUL) ? wp->w_p_stl : p_stl); opt_scope = ((*wp->w_p_stl != NUL) ? OPT_LOCAL : 0); } @@ -402,7 +402,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) // Make a copy, because the statusline may include a function call that // might change the option value and free the memory. stl = xstrdup(stl); - build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, opt_scope, + build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_idx, opt_scope, fillchar, maxwidth, &hltab, &tabtab, NULL); xfree(stl); @@ -881,7 +881,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * StlClickRecord *clickrec; char *stc = xstrdup(wp->w_p_stc); - int width = build_stl_str_hl(wp, stcp->text, MAXPATHL, stc, "statuscolumn", OPT_LOCAL, ' ', + int width = build_stl_str_hl(wp, stcp->text, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, ' ', stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp); xfree(stc); @@ -913,8 +913,8 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * /// Note: This should not be NameBuff /// @param outlen The length of the output buffer /// @param fmt The statusline format string -/// @param opt_name The option name corresponding to "fmt" -/// @param opt_scope The scope corresponding to "opt_name" +/// @param opt_idx Index of the option corresponding to "fmt" +/// @param opt_scope The scope corresponding to "opt_idx" /// @param fillchar Character to use when filling empty space in the statusline /// @param maxwidth The maximum width to make the statusline /// @param hltab HL attributes (can be NULL) @@ -922,7 +922,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * /// @param stcp Status column attributes (can be NULL) /// /// @return The final width of the statusline -int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_name, int opt_scope, +int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int opt_idx, int opt_scope, int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab, statuscol_T *stcp) { @@ -957,10 +957,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n stl_separator_locations = xmalloc(sizeof(int) * stl_items_len); } - // if "fmt" was set insecurely it needs to be evaluated in the sandbox - // "opt_name" will be NULL when caller is nvim_eval_statusline() - const int use_sandbox = opt_name ? was_set_insecurely(wp, opt_name, opt_scope) - : false; + // If "fmt" was set insecurely it needs to be evaluated in the sandbox. + // "opt_idx" will be -1 when caller is nvim_eval_statusline(). + const int use_sandbox = (opt_idx != -1) ? was_set_insecurely(wp, opt_idx, opt_scope) : false; // When the format starts with "%!" then evaluate it as an expression and // use the result as the actual format string. @@ -1545,7 +1544,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n break; case STL_SHOWCMD: - if (p_sc && (opt_name == NULL || strcmp(opt_name, p_sloc) == 0)) { + if (p_sc && (opt_idx == -1 || findoption(p_sloc) == opt_idx)) { str = showcmd_buf; } break; @@ -2177,8 +2176,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // TODO(Bram): find out why using called_emsg_before makes tests fail, does it // matter? // if (called_emsg > called_emsg_before) - if (opt_name && did_emsg > did_emsg_before) { - set_string_option_direct(opt_name, -1, "", OPT_FREE | opt_scope, SID_ERROR); + if (opt_idx != -1 && did_emsg > did_emsg_before) { + set_string_option_direct(opt_idx, "", OPT_FREE | opt_scope, SID_ERROR); } // A user function may reset KeyTyped, restore it. diff --git a/src/nvim/statusline.h b/src/nvim/statusline.h index eab7c1aa47..59a900d566 100644 --- a/src/nvim/statusline.h +++ b/src/nvim/statusline.h @@ -4,6 +4,7 @@ #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" +#include "nvim/option_defs.h" #include "nvim/statusline_defs.h" // IWYU pragma: export /// Array defining what should be done when tabline is clicked diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index fda6aa41e8..af9693c4b0 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -233,7 +233,7 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts) aucmd_prepbuf(&aco, buf); refresh_screen(rv, buf); - set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("terminal"), OPT_LOCAL); + set_option_value(kOptBuftype, STATIC_CSTR_AS_OPTVAL("terminal"), OPT_LOCAL); // Default settings for terminal buffers buf->b_p_ma = false; // 'nomodifiable' @@ -241,8 +241,8 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts) buf->b_p_scbk = // 'scrollback' (initialize local from global) (p_scbk < 0) ? 10000 : MAX(1, p_scbk); buf->b_p_tw = 0; // 'textwidth' - set_option_value("wrap", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value("list", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value(kOptWrap, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value(kOptList, BOOLEAN_OPTVAL(false), OPT_LOCAL); if (buf->b_ffname != NULL) { buf_set_term_title(buf, buf->b_ffname, strlen(buf->b_ffname)); } diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 8e52ad660b..3484d104fd 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -870,7 +870,7 @@ void op_formatexpr(oparg_T *oap) /// @param c character to be inserted int fex_format(linenr_T lnum, long count, int c) { - int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, kOptFormatexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Set v:lnum to the first line number and v:count to the number of lines. diff --git a/src/nvim/ui.c b/src/nvim/ui.c index a78a5b077f..0fc0c5bf86 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -235,7 +235,7 @@ void ui_refresh(void) p_lz = save_p_lz; if (ext_widgets[kUIMessages]) { - set_option_value("cmdheight", NUMBER_OPTVAL(0), 0); + set_option_value(kOptCmdheight, NUMBER_OPTVAL(0), 0); command_height(); } ui_mode_info_set(); diff --git a/src/nvim/window.c b/src/nvim/window.c index ef1ef89d95..98c62d6f44 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5183,7 +5183,7 @@ void win_new_screensize(void) if (old_Rows != Rows) { // If 'window' uses the whole screen, keep it using that. // Don't change it when set with "-w size" on the command line. - if (p_window == old_Rows - 1 || (old_Rows == 0 && !option_was_set("window"))) { + if (p_window == old_Rows - 1 || (old_Rows == 0 && !option_was_set(kOptWindow))) { p_window = Rows - 1; } old_Rows = Rows; -- cgit From bf3bc1cec9f00b9644815001a8732ecedf3ce07f Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 7 Dec 2023 23:59:30 +0600 Subject: refactor(options): convert `opt_idx` variables to `OptIndex` --- src/nvim/api/deprecated.c | 4 +- src/nvim/api/options.c | 34 +++---- src/nvim/eval.c | 4 +- src/nvim/eval/vars.c | 6 +- src/nvim/generators/gen_options.lua | 1 + src/nvim/option.c | 191 ++++++++++++++++++------------------ src/nvim/optionstr.c | 8 +- src/nvim/statusline.c | 17 ++-- 8 files changed, 133 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 34bf029483..371361c5a1 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -669,8 +669,8 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, return; }); - int opt_idx = findoption(name.data); - VALIDATE_S(opt_idx >= 0, "option name", name.data, { + OptIndex opt_idx = findoption(name.data); + VALIDATE_S(opt_idx != kOptInvalid, "option name", name.data, { return; }); diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 0d18c7871c..54a2fbf385 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -23,9 +23,9 @@ # include "api/options.c.generated.h" #endif -static int validate_option_value_args(Dict(option) *opts, char *name, int *opt_idx, int *scope, - OptReqScope *req_scope, void **from, char **filetype, - Error *err) +static int validate_option_value_args(Dict(option) *opts, char *name, OptIndex *opt_idxp, + int *scope, OptReqScope *req_scope, void **from, + char **filetype, Error *err) { #define HAS_KEY_X(d, v) HAS_KEY(d, option, v) if (HAS_KEY_X(opts, scope)) { @@ -79,8 +79,8 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *opt_i return FAIL; }); - *opt_idx = findoption(name); - int flags = get_option_attrs(*opt_idx); + *opt_idxp = findoption(name); + int flags = get_option_attrs(*opt_idxp); if (flags == 0) { // hidden or unknown option api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name); @@ -153,7 +153,7 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(9) { - int opt_idx = 0; + OptIndex opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; @@ -219,7 +219,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( Error *err) FUNC_API_SINCE(9) { - int opt_idx = 0; + OptIndex opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *to = NULL; @@ -306,7 +306,7 @@ Dictionary nvim_get_all_options_info(Error *err) Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(11) { - int opt_idx = 0; + OptIndex opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; @@ -392,9 +392,9 @@ static void restore_option_context(void *const ctx, OptReqScope req_scope) /// @return Option attributes. /// 0 for hidden or unknown option. /// See SOPT_* in option_defs.h for other flags. -int get_option_attrs(int opt_idx) +int get_option_attrs(OptIndex opt_idx) { - if (opt_idx < 0) { + if (opt_idx == kOptInvalid) { return 0; } @@ -425,9 +425,9 @@ int get_option_attrs(int opt_idx) /// @param req_scope Requested option scope. See OptReqScope in option.h. /// /// @return true if option has a value in the requested scope, false otherwise. -static bool option_has_scope(int opt_idx, OptReqScope req_scope) +static bool option_has_scope(OptIndex opt_idx, OptReqScope req_scope) { - if (opt_idx < 0) { + if (opt_idx == kOptInvalid) { return false; } @@ -463,9 +463,9 @@ static bool option_has_scope(int opt_idx, OptReqScope req_scope) /// @return Option value in the requested scope. Returns a Nil option value if option is not found, /// hidden or if it isn't present in the requested scope. (i.e. has no global, window-local or /// buffer-local value depending on opt_scope). -OptVal get_option_value_strict(int opt_idx, OptReqScope req_scope, void *from, Error *err) +OptVal get_option_value_strict(OptIndex opt_idx, OptReqScope req_scope, void *from, Error *err) { - if (opt_idx < 0 || !option_has_scope(opt_idx, req_scope)) { + if (opt_idx == kOptInvalid || !option_has_scope(opt_idx, req_scope)) { return NIL_OPTVAL; } @@ -500,8 +500,8 @@ OptVal get_option_value_strict(int opt_idx, OptReqScope req_scope, void *from, E /// @param[out] err Error message, if any. /// /// @return Option value. Must be freed by caller. -OptVal get_option_value_for(int opt_idx, int scope, const OptReqScope req_scope, void *const from, - Error *err) +OptVal get_option_value_for(OptIndex opt_idx, int scope, const OptReqScope req_scope, + void *const from, Error *err) { switchwin_T switchwin; aco_save_T aco; @@ -531,7 +531,7 @@ OptVal get_option_value_for(int opt_idx, int scope, const OptReqScope req_scope, /// @param req_scope Requested option scope. See OptReqScope in option.h. /// @param[in] from Target buffer/window. /// @param[out] err Error message, if any. -void set_option_value_for(const char *name, int opt_idx, OptVal value, const int opt_flags, +void set_option_value_for(const char *name, OptIndex opt_idx, OptVal value, const int opt_flags, const OptReqScope req_scope, void *const from, Error *err) FUNC_ATTR_NONNULL_ARG(1) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1c30075991..1fdaa95076 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3788,9 +3788,9 @@ int eval_option(const char **const arg, typval_T *const rettv, const bool evalua *option_end = NUL; bool is_tty_opt = is_tty_option(*arg); - int opt_idx = is_tty_opt ? -1 : findoption(*arg); + OptIndex opt_idx = is_tty_opt ? kOptInvalid : findoption(*arg); - if (opt_idx < 0 && !is_tty_opt) { + if (opt_idx == kOptInvalid && !is_tty_opt) { // Only give error if result is going to be used. if (rettv != NULL) { semsg(_("E113: Unknown option: %s"), *arg); diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 9b7a61f969..73c8ae1191 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -774,7 +774,7 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, *p = NUL; bool is_tty_opt = is_tty_option(arg); - int opt_idx = is_tty_opt ? -1 : findoption(arg); + OptIndex opt_idx = is_tty_opt ? kOptInvalid : findoption(arg); uint32_t opt_p_flags = get_option_flags(opt_idx); bool hidden = is_option_hidden(opt_idx); OptVal curval = is_tty_opt ? get_tty_option(arg) : get_option_value(opt_idx, scope); @@ -1940,8 +1940,8 @@ typval_T optval_as_tv(OptVal value) /// Set option "varname" to the value of "varp" for the current buffer/window. static void set_option_from_tv(const char *varname, typval_T *varp) { - int opt_idx = findoption(varname); - if (opt_idx < 0) { + OptIndex opt_idx = findoption(varname); + if (opt_idx == kOptInvalid) { semsg(_(e_unknown_option2), varname); return; } diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 2b17add7ba..7c5fc08129 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -241,6 +241,7 @@ end opt_fd = assert(io.open(options_enum_file, 'w')) w('typedef enum {') +w(' kOptInvalid = -1,') for i, o in ipairs(options.options) do w((' kOpt%s = %u,'):format(title_case(o.full_name), i - 1)) end diff --git a/src/nvim/option.c b/src/nvim/option.c index 71d9a2800c..cf469d6e5e 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -157,12 +157,12 @@ typedef enum { #endif static int p_bin_dep_opts[] = { - kOptTextwidth, kOptWrapmargin, kOptModeline, kOptExpandtab, -1 + kOptTextwidth, kOptWrapmargin, kOptModeline, kOptExpandtab, kOptInvalid }; static int p_paste_dep_opts[] = { - kOptAutoindent, kOptExpandtab, kOptRuler, kOptShowmatch, kOptSmarttab, - kOptSofttabstop, kOptTextwidth, kOptWrapmargin, kOptRevins, kOptVarsofttabstop, -1 + kOptAutoindent, kOptExpandtab, kOptRuler, kOptShowmatch, kOptSmarttab, kOptSofttabstop, + kOptTextwidth, kOptWrapmargin, kOptRevins, kOptVarsofttabstop, kOptInvalid }; void set_init_tablocal(void) @@ -199,7 +199,7 @@ static void set_init_default_backupskip(void) static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" }; #endif garray_T ga; - int opt_idx = kOptBackupskip; + OptIndex opt_idx = kOptBackupskip; ga_init(&ga, 1, 100); for (size_t n = 0; n < ARRAY_SIZE(names); n++) { @@ -269,8 +269,8 @@ static void set_init_default_cdpath(void) } } buf[j] = NUL; - int opt_idx = kOptCdpath; - if (opt_idx >= 0) { + OptIndex opt_idx = kOptCdpath; + if (opt_idx != kOptInvalid) { options[opt_idx].def_val = buf; options[opt_idx].flags |= P_DEF_ALLOCED; } else { @@ -288,7 +288,7 @@ static void set_init_default_cdpath(void) /// default. static void set_init_expand_env(void) { - for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + for (OptIndex opt_idx = 0; options[opt_idx].fullname; opt_idx++) { vimoption_T *opt = &options[opt_idx]; if (opt->flags & P_NO_DEF_EXP) { continue; @@ -420,7 +420,7 @@ void set_init_1(bool clean_arg) /// This does not take care of side effects! /// /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL -static void set_option_default(const int opt_idx, int opt_flags) +static void set_option_default(const OptIndex opt_idx, int opt_flags) { int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; @@ -507,10 +507,10 @@ static void set_options_default(int opt_flags) /// @param opt_idx Option index in options[] table. /// @param val The value of the option. /// @param allocated If true, do not copy default as it was already allocated. -static void set_string_default(int opt_idx, char *val, bool allocated) +static void set_string_default(OptIndex opt_idx, char *val, bool allocated) FUNC_ATTR_NONNULL_ALL { - if (opt_idx < 0) { + if (opt_idx == kOptInvalid) { return; } @@ -556,9 +556,9 @@ static char *find_dup_item(char *origval, const char *newval, uint32_t flags) /// Set the Vi-default value of a number option. /// Used for 'lines' and 'columns'. -void set_number_default(int opt_idx, OptInt val) +void set_number_default(OptIndex opt_idx, OptInt val) { - if (opt_idx >= 0) { + if (opt_idx != kOptInvalid) { options[opt_idx].def_val = (void *)(intptr_t)val; } } @@ -744,7 +744,7 @@ void ex_set(exarg_T *eap) } /// Get the default value for a string option. -static char *stropt_get_default_val(int opt_idx, uint64_t flags) +static char *stropt_get_default_val(OptIndex opt_idx, uint64_t flags) { char *newval = options[opt_idx].def_val; // expand environment variables and ~ since the default value was @@ -813,7 +813,7 @@ static char *stropt_copy_value(char *origval, char **argp, set_op_T op, } /// Expand environment variables and ~ in string option value 'newval'. -static char *stropt_expand_envvar(int opt_idx, char *origval, char *newval, set_op_T op) +static char *stropt_expand_envvar(OptIndex opt_idx, char *origval, char *newval, set_op_T op) { char *s = option_expand(opt_idx, newval); if (s == NULL) { @@ -913,8 +913,8 @@ static void stropt_remove_dupflags(char *newval, uint32_t flags) /// set {opt}< /// set {opt}={val} /// set {opt}:{val} -static char *stropt_get_newval(int nextchar, int opt_idx, char **argp, void *varp, char *origval, - set_op_T *op_arg, uint32_t flags) +static char *stropt_get_newval(int nextchar, OptIndex opt_idx, char **argp, void *varp, + char *origval, set_op_T *op_arg, uint32_t flags) { char *arg = *argp; set_op_T op = *op_arg; @@ -1020,15 +1020,15 @@ static set_prefix_T get_option_prefix(char **argp) /// @param[out] keyp /// @param[out] len Length of option name /// @return FAIL if an error is detected, OK otherwise -static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) +static int parse_option_name(char *arg, int *keyp, int *lenp, OptIndex *opt_idxp) { // find end of name int key = 0; int len; - int opt_idx; + OptIndex opt_idx; if (*arg == '<') { - opt_idx = -1; + opt_idx = kOptInvalid; // look out for ;> if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4]) { len = 5; @@ -1045,7 +1045,7 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) opt_idx = findoption_len(arg + 1, (size_t)(len - 1)); } len++; - if (opt_idx == -1) { + if (opt_idx == kOptInvalid) { key = find_key_option(arg + 1, true); } } else { @@ -1059,7 +1059,7 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) } } opt_idx = findoption_len(arg, (size_t)len); - if (opt_idx == -1) { + if (opt_idx == kOptInvalid) { key = find_key_option(arg, false); } } @@ -1071,7 +1071,7 @@ static int parse_option_name(char *arg, int *keyp, int *lenp, int *opt_idxp) return OK; } -static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t flags, +static int validate_opt_idx(win_T *win, OptIndex opt_idx, int opt_flags, uint32_t flags, set_prefix_T prefix, const char **errmsg) { // Only bools can have a prefix of 'inv' or 'no' @@ -1083,12 +1083,12 @@ static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t fla // Skip all options that are not window-local (used when showing // an already loaded buffer in a window). if ((opt_flags & OPT_WINONLY) - && (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) { + && (opt_idx == kOptInvalid || options[opt_idx].var != VAR_WIN)) { return FAIL; } // Skip all options that are window-local (used for :vimgrep). - if ((opt_flags & OPT_NOWIN) && opt_idx >= 0 + if ((opt_flags & OPT_NOWIN) && opt_idx != kOptInvalid && options[opt_idx].var == VAR_WIN) { return FAIL; } @@ -1107,7 +1107,7 @@ static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t fla // 'foldmethod' becomes "marker" instead of "diff" and that // "wrap" gets set. if (win->w_p_diff - && opt_idx >= 0 // shut up coverity warning + && opt_idx != kOptInvalid // shut up coverity warning && (options[opt_idx].indir == PV_FDM || options[opt_idx].indir == PV_WRAP)) { return FAIL; @@ -1124,7 +1124,7 @@ static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t fla } /// Get new option value from argp. Allocated OptVal must be freed by caller. -static OptVal get_option_newval(int opt_idx, int opt_flags, set_prefix_T prefix, char **argp, +static OptVal get_option_newval(OptIndex opt_idx, int opt_flags, set_prefix_T prefix, char **argp, int nextchar, set_op_T op, uint32_t flags, void *varp, char *errbuf, const size_t errbuflen, const char **errmsg) FUNC_ATTR_WARN_UNUSED_RESULT @@ -1264,7 +1264,7 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * // find end of name int key = 0; int len; - int opt_idx; + OptIndex opt_idx; if (parse_option_name(arg, &key, &len, &opt_idx) == FAIL) { *errmsg = e_invarg; return; @@ -1285,7 +1285,7 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * uint8_t nextchar = (uint8_t)arg[len]; // next non-white char after option name - if (opt_idx == -1 && key == 0) { // found a mismatch: skip + if (opt_idx == kOptInvalid && key == 0) { // found a mismatch: skip *errmsg = e_unknown_option; return; } @@ -1293,7 +1293,7 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * uint32_t flags; // flags for current option void *varp = NULL; // pointer to variable for current option - if (opt_idx >= 0) { + if (opt_idx != kOptInvalid) { if (options[opt_idx].var == NULL) { // hidden option: skip // Only give an error message when requesting the value of // a hidden option, ignore setting it. @@ -1346,7 +1346,7 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * gotocmdline(true); // cursor at status line *did_show = true; // remember that we did a line } - if (opt_idx >= 0) { + if (opt_idx != kOptInvalid) { showoneopt(&options[opt_idx], opt_flags); if (p_verbose > 0) { // Mention where the option was last set. @@ -1614,7 +1614,7 @@ char *find_shada_parameter(int type) /// These string options cannot be indirect! /// If "val" is NULL expand the current value of the option. /// Return pointer to NameBuff, or NULL when not expanded. -static char *option_expand(int opt_idx, char *val) +static char *option_expand(OptIndex opt_idx, char *val) { // if option doesn't need expansion nothing to do if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL) { @@ -1689,7 +1689,7 @@ static void didset_options2(void) /// Check for string options that are NULL (normally only termcap options). void check_options(void) { - for (int opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++) { + for (OptIndex opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++) { if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL) { check_string_option((char **)get_varp(&(options[opt_idx]))); } @@ -1703,9 +1703,9 @@ void check_options(void) /// @param opt_flags Option flags. /// /// @return True if option was set from a modeline or in secure mode, false if it wasn't. -int was_set_insecurely(win_T *const wp, int opt_idx, int opt_flags) +int was_set_insecurely(win_T *const wp, OptIndex opt_idx, int opt_flags) { - assert(opt_idx >= 0); + assert(opt_idx != kOptInvalid); uint32_t *flagp = insecure_flag(wp, opt_idx, opt_flags); return (*flagp & P_INSECURE) != 0; @@ -1715,7 +1715,7 @@ int was_set_insecurely(win_T *const wp, int opt_idx, int opt_flags) /// "opt_idx". For some local options a local flags field is used. /// NOTE: Caller must make sure that "wp" is set to the window from which /// the option is used. -uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags) +uint32_t *insecure_flag(win_T *const wp, OptIndex opt_idx, int opt_flags) { if (opt_flags & OPT_LOCAL) { assert(wp != NULL); @@ -1819,15 +1819,15 @@ bool parse_winhl_opt(win_T *wp) } /// Get the script context of global option at index opt_idx. -sctx_T *get_option_sctx(int opt_idx) +sctx_T *get_option_sctx(OptIndex opt_idx) { - assert(opt_idx >= 0); + assert(opt_idx != kOptInvalid); return &options[opt_idx].last_set.script_ctx; } /// Set the script_ctx for an option, taking care of setting the buffer- or /// window-local value. -void set_option_sctx(int opt_idx, int opt_flags, sctx_T script_ctx) +void set_option_sctx(OptIndex opt_idx, int opt_flags, sctx_T script_ctx) { int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; int indir = (int)options[opt_idx].indir; @@ -1861,7 +1861,7 @@ void set_option_sctx(int opt_idx, int opt_flags, sctx_T script_ctx) } /// Apply the OptionSet autocommand. -static void apply_optionset_autocmd(int opt_idx, int opt_flags, OptVal oldval, OptVal oldval_g, +static void apply_optionset_autocmd(OptIndex opt_idx, int opt_flags, OptVal oldval, OptVal oldval_g, OptVal oldval_l, OptVal newval, const char *errmsg) { // Don't do this while starting up, failure or recursively. @@ -3013,8 +3013,8 @@ void check_redraw(uint32_t flags) /// @param[in] arg Option to find index for. /// @param[in] len Length of the option. /// -/// @return Index of the option or -1 if option was not found. -int findoption_len(const char *const arg, const size_t len) +/// @return Index of the option or kOptInvalid if option was not found. +OptIndex findoption_len(const char *const arg, const size_t len) { const char *s; static int quick_tab[27] = { 0, 0 }; // quick access table @@ -3038,10 +3038,10 @@ int findoption_len(const char *const arg, const size_t len) // Check for name starting with an illegal character. if (len == 0 || arg[0] < 'a' || arg[0] > 'z') { - return -1; + return kOptInvalid; } - int opt_idx; + OptIndex opt_idx; const bool is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_'); if (is_term_opt) { opt_idx = quick_tab[26]; @@ -3069,7 +3069,7 @@ int findoption_len(const char *const arg, const size_t len) } } if (s == NULL) { - opt_idx = -1; + opt_idx = kOptInvalid; } else { // Nvim: handle option aliases. if (strncmp(options[opt_idx].fullname, "viminfo", 7) == 0) { @@ -3143,8 +3143,8 @@ bool set_tty_option(const char *name, char *value) /// /// @param[in] arg Option name. /// -/// @return Option index or -1 if option was not found. -int findoption(const char *const arg) +/// @return Option index or kOptInvalid if option was not found. +OptIndex findoption(const char *const arg) FUNC_ATTR_NONNULL_ALL { return findoption_len(arg, strlen(arg)); @@ -3204,9 +3204,9 @@ bool optval_equal(OptVal o1, OptVal o2) /// Match type of OptVal with the type of the target option. Returns true if the types match and /// false otherwise. -static bool optval_match_type(OptVal o, int opt_idx) +static bool optval_match_type(OptVal o, OptIndex opt_idx) { - assert(opt_idx >= 0); + assert(opt_idx != kOptInvalid); uint32_t flags = options[opt_idx].flags; switch (o.type) { @@ -3226,7 +3226,7 @@ static bool optval_match_type(OptVal o, int opt_idx) /// /// @param opt_idx Option index in options[] table. /// @param[out] varp Pointer to option variable. -OptVal optval_from_varp(int opt_idx, void *varp) +OptVal optval_from_varp(OptIndex opt_idx, void *varp) { // Special case: 'modified' is b_changed, but we also want to consider it set when 'ff' or 'fenc' // changed. @@ -3266,7 +3266,7 @@ OptVal optval_from_varp(int opt_idx, void *varp) /// @param[out] varp Pointer to option variable. /// @param[in] value New option value. /// @param free_oldval Free old value. -static void set_option_varp(int opt_idx, void *varp, OptVal value, bool free_oldval) +static void set_option_varp(OptIndex opt_idx, void *varp, OptVal value, bool free_oldval) FUNC_ATTR_NONNULL_ARG(2) { assert(optval_match_type(value, opt_idx)); @@ -3362,7 +3362,7 @@ OptVal object_as_optval(Object o, bool *error) /// @param[in] varp Pointer to option variable. /// /// @return [allocated] Option value equal to the unset value for the option. -static OptVal optval_unset_local(int opt_idx, void *varp) +static OptVal optval_unset_local(OptIndex opt_idx, void *varp) { vimoption_T *opt = &options[opt_idx]; // For global-local options, use the unset value of the local value. @@ -3391,7 +3391,7 @@ static OptVal optval_unset_local(int opt_idx, void *varp) /// For options with a singular type, it returns the name of the type. For options with multiple /// possible types, it returns a slash separated list of types. For example, if an option can be a /// number, boolean or string, the function returns "Number/Boolean/String" -static char *option_get_valid_types(int opt_idx) +static char *option_get_valid_types(OptIndex opt_idx) { uint32_t flags = options[opt_idx].flags; uint32_t type_count = 0; @@ -3435,9 +3435,9 @@ static char *option_get_valid_types(int opt_idx) /// @param opt_idx Option index in options[] table. /// /// @return True if option is hidden, false otherwise. Returns false if option name is invalid. -bool is_option_hidden(int opt_idx) +bool is_option_hidden(OptIndex opt_idx) { - return opt_idx < 0 ? false : get_varp(&options[opt_idx]) == NULL; + return opt_idx == kOptInvalid ? false : get_varp(&options[opt_idx]) == NULL; } /// Get option flags. @@ -3445,9 +3445,9 @@ bool is_option_hidden(int opt_idx) /// @param opt_idx Option index in options[] table. /// /// @return Option flags. Returns 0 for invalid option name. -uint32_t get_option_flags(int opt_idx) +uint32_t get_option_flags(OptIndex opt_idx) { - return opt_idx < 0 ? 0 : options[opt_idx].flags; + return opt_idx == kOptInvalid ? 0 : options[opt_idx].flags; } /// Gets the value for an option. @@ -3456,9 +3456,9 @@ uint32_t get_option_flags(int opt_idx) /// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). /// /// @return [allocated] Option value. Returns NIL_OPTVAL for invalid option index. -OptVal get_option_value(int opt_idx, int scope) +OptVal get_option_value(OptIndex opt_idx, int scope) { - if (opt_idx < 0) { // option not in the options[] table. + if (opt_idx == kOptInvalid) { // option not in the options[] table. return NIL_OPTVAL; } @@ -3469,8 +3469,9 @@ OptVal get_option_value(int opt_idx, int scope) } /// Return information for option at 'opt_idx' -vimoption_T *get_option(int opt_idx) +vimoption_T *get_option(OptIndex opt_idx) { + assert(opt_idx != kOptInvalid); return &options[opt_idx]; } @@ -3496,7 +3497,7 @@ static bool is_option_local_value_unset(vimoption_T *opt, buf_T *buf, win_T *win /// Handle side-effects of setting an option. /// -/// @param opt_idx Index in options[] table. Must be >= 0. +/// @param opt_idx Index in options[] table. Must not be kOptInvalid. /// @param[in] varp Option variable pointer, cannot be NULL. /// @param old_value Old option value. /// @param new_value New option value. @@ -3507,7 +3508,7 @@ static bool is_option_local_value_unset(vimoption_T *opt, buf_T *buf, win_T *win /// @param errbuflen Length of error buffer. /// /// @return NULL on success, an untranslated error message on error. -static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, OptVal new_value, +static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value, OptVal new_value, int opt_flags, bool *value_checked, bool value_replaced, char *errbuf, size_t errbuflen) { @@ -3654,7 +3655,7 @@ static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, Opt /// Set the value of an option using an OptVal. /// -/// @param opt_idx Index in options[] table. Must be >= 0. +/// @param opt_idx Index in options[] table. Must not be kOptInvalid. /// @param[in] varp Option variable pointer, cannot be NULL. /// @param value New option value. Might get freed. /// @param opt_flags Option flags. @@ -3663,10 +3664,10 @@ static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, Opt /// @param errbuflen Length of error buffer. /// /// @return NULL on success, an untranslated error message on error. -static const char *set_option(const int opt_idx, void *varp, OptVal value, int opt_flags, +static const char *set_option(const OptIndex opt_idx, void *varp, OptVal value, int opt_flags, const bool value_replaced, char *errbuf, size_t errbuflen) { - assert(opt_idx >= 0 && varp != NULL); + assert(opt_idx != kOptInvalid && varp != NULL); const char *errmsg = NULL; bool value_checked = false; @@ -3796,14 +3797,14 @@ err: /// Set the value of an option. /// -/// @param opt_idx Index in options[] table. Must be >= 0. +/// @param opt_idx Index in options[] table. Must not be kOptInvalid. /// @param[in] value Option value. If NIL_OPTVAL, the option value is cleared. /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). /// /// @return NULL on success, an untranslated error message on error. -const char *set_option_value(const int opt_idx, const OptVal value, int opt_flags) +const char *set_option_value(const OptIndex opt_idx, const OptVal value, int opt_flags) { - assert(opt_idx >= 0); + assert(opt_idx != kOptInvalid); static char errbuf[IOSIZE]; uint32_t flags = options[opt_idx].flags; @@ -3832,13 +3833,13 @@ const char *set_option_value(const int opt_idx, const OptVal value, int opt_flag /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). /// /// @return NULL on success, an untranslated error message on error. -const char *set_option_value_handle_tty(const char *name, int opt_idx, const OptVal value, +const char *set_option_value_handle_tty(const char *name, OptIndex opt_idx, const OptVal value, int opt_flags) FUNC_ATTR_NONNULL_ARG(1) { static char errbuf[IOSIZE]; - if (opt_idx < 0) { + if (opt_idx == kOptInvalid) { if (is_tty_option(name)) { return NULL; // Fail silently; many old vimrcs set t_xx options. } @@ -3855,7 +3856,7 @@ const char *set_option_value_handle_tty(const char *name, int opt_idx, const Opt /// @param opt_idx Option index in options[] table. /// @param value Option value. If NIL_OPTVAL, the option value is cleared. /// @param opt_flags OPT_LOCAL or 0 (both) -void set_option_value_give_err(const int opt_idx, OptVal value, int opt_flags) +void set_option_value_give_err(const OptIndex opt_idx, OptVal value, int opt_flags) { const char *errmsg = set_option_value(opt_idx, value, opt_flags); @@ -4003,7 +4004,7 @@ static int optval_default(vimoption_T *p, const void *varp) /// Send update to UIs with values of UI relevant options void ui_refresh_options(void) { - for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + for (OptIndex opt_idx = 0; options[opt_idx].fullname; opt_idx++) { uint32_t flags = options[opt_idx].flags; if (!(flags & P_UI_OPTION)) { continue; @@ -4382,7 +4383,7 @@ void *get_varp_scope(vimoption_T *p, int scope) /// Get pointer to option variable at 'opt_idx', depending on local or global /// scope. -void *get_option_varp_scope_from(int opt_idx, int scope, buf_T *buf, win_T *win) +void *get_option_varp_scope_from(OptIndex opt_idx, int scope, buf_T *buf, win_T *win) { return get_varp_scope_from(&(options[opt_idx]), scope, buf, win); } @@ -4849,19 +4850,19 @@ void didset_window_options(win_T *wp, bool valid_cursor) } /// Index into the options table for a buffer-local option enum. -static int buf_opt_idx[BV_COUNT]; +static OptIndex buf_opt_idx[BV_COUNT]; #define COPY_OPT_SCTX(buf, bv) buf->b_p_script_ctx[bv] = options[buf_opt_idx[bv]].last_set /// Initialize buf_opt_idx[] if not done already. static void init_buf_opt_idx(void) { - static int did_init_buf_opt_idx = false; + static bool did_init_buf_opt_idx = false; if (did_init_buf_opt_idx) { return; } did_init_buf_opt_idx = true; - for (int i = 0; options[i].fullname != NULL; i++) { + for (OptIndex i = 0; options[i].fullname != NULL; i++) { if (options[i].indir & PV_BUF) { buf_opt_idx[options[i].indir & PV_MASK] = i; } @@ -5167,7 +5168,7 @@ void set_imsearch_global(buf_T *buf) p_imsearch = buf->b_p_imsearch; } -static int expand_option_idx = -1; +static int expand_option_idx = kOptInvalid; static int expand_option_start_col = 0; static char expand_option_name[5] = { 't', '_', NUL, NUL, NUL }; static int expand_option_flags = 0; @@ -5217,7 +5218,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) char nextchar; uint32_t flags = 0; - int opt_idx = 0; + OptIndex opt_idx = 0; int is_term_option = false; if (*arg == '<') { @@ -5258,7 +5259,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) } nextchar = *p; opt_idx = findoption_len(arg, (size_t)(p - arg)); - if (opt_idx == -1 || options[opt_idx].var == NULL) { + if (opt_idx == kOptInvalid || options[opt_idx].var == NULL) { xp->xp_context = EXPAND_NOTHING; return; } @@ -5291,7 +5292,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) // Below are for handling expanding a specific option's value after the '=' or ':' if (is_term_option) { - expand_option_idx = -1; + expand_option_idx = kOptInvalid; } else { expand_option_idx = opt_idx; } @@ -5315,8 +5316,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) if (expand_option_subtract) { xp->xp_context = EXPAND_SETTING_SUBTRACT; return; - } else if (expand_option_idx >= 0 - && options[expand_option_idx].opt_expand_cb != NULL) { + } else if (expand_option_idx != kOptInvalid && options[expand_option_idx].opt_expand_cb != NULL) { xp->xp_context = EXPAND_STRING_SETTING; } else if (*xp->xp_pattern == NUL) { xp->xp_context = EXPAND_OLD_SETTING; @@ -5542,7 +5542,7 @@ static char *escape_option_str_cmdline(char *var) // The reverse is found at stropt_copy_value(). for (var = buf; *var != NUL; MB_PTR_ADV(var)) { if (var[0] == '\\' && var[1] == '\\' - && expand_option_idx >= 0 + && expand_option_idx != kOptInvalid && (options[expand_option_idx].flags & P_EXPAND) && vim_isfilec((uint8_t)var[2]) && (var[2] != '\\' || (var == buf && var[4] != '\\'))) { @@ -5561,12 +5561,12 @@ int ExpandOldSetting(int *numMatches, char ***matches) *numMatches = 0; *matches = xmalloc(sizeof(char *)); - // For a terminal key code expand_option_idx is < 0. - if (expand_option_idx < 0) { + // For a terminal key code expand_option_idx is kOptInvalid. + if (expand_option_idx == kOptInvalid) { expand_option_idx = findoption(expand_option_name); } - if (expand_option_idx >= 0) { + if (expand_option_idx != kOptInvalid) { // Put string of option value in NameBuff. option_value2string(&options[expand_option_idx], expand_option_flags); var = NameBuff; @@ -5584,8 +5584,7 @@ int ExpandOldSetting(int *numMatches, char ***matches) /// Expansion handler for :set=/:set+= when the option has a custom expansion handler. int ExpandStringSetting(expand_T *xp, regmatch_T *regmatch, int *numMatches, char ***matches) { - if (expand_option_idx < 0 - || options[expand_option_idx].opt_expand_cb == NULL) { + if (expand_option_idx == kOptInvalid || options[expand_option_idx].opt_expand_cb == NULL) { // Not supposed to reach this. This function is only for options with // custom expansion callbacks. return FAIL; @@ -5617,7 +5616,7 @@ int ExpandStringSetting(expand_T *xp, regmatch_T *regmatch, int *numMatches, cha /// Expansion handler for :set-= int ExpandSettingSubtract(expand_T *xp, regmatch_T *regmatch, int *numMatches, char ***matches) { - if (expand_option_idx < 0) { + if (expand_option_idx == kOptInvalid) { // term option return ExpandOldSetting(numMatches, matches); } @@ -5802,18 +5801,18 @@ void vimrc_found(char *fname, char *envname) /// @param[in] name Option name. /// /// @return True if option was set. -bool option_was_set(int opt_idx) +bool option_was_set(OptIndex opt_idx) { - assert(opt_idx >= 0); + assert(opt_idx != kOptInvalid); return options[opt_idx].flags & P_WAS_SET; } /// Reset the flag indicating option "name" was set. /// /// @param[in] name Option name. -void reset_option_was_set(int opt_idx) +void reset_option_was_set(OptIndex opt_idx) { - assert(opt_idx >= 0); + assert(opt_idx != kOptInvalid); options[opt_idx].flags &= ~P_WAS_SET; } @@ -5916,7 +5915,7 @@ int option_set_callback_func(char *optval, Callback *optcb) static void didset_options_sctx(int opt_flags, int *buf) { for (int i = 0;; i++) { - if (buf[i] == -1) { + if (buf[i] == kOptInvalid) { break; } @@ -6137,7 +6136,7 @@ dict_T *get_winbuf_options(const int bufopt) { dict_T *const d = tv_dict_alloc(); - for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + for (OptIndex opt_idx = 0; options[opt_idx].fullname; opt_idx++) { struct vimoption *opt = &options[opt_idx]; if ((bufopt && (opt->indir & PV_BUF)) @@ -6181,8 +6180,8 @@ int get_sidescrolloff_value(win_T *wp) Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Error *err) { - int opt_idx = findoption_len(name.data, name.size); - VALIDATE_S(opt_idx >= 0, "option (not found)", name.data, { + OptIndex opt_idx = findoption_len(name.data, name.size); + VALIDATE_S(opt_idx != kOptInvalid, "option (not found)", name.data, { return (Dictionary)ARRAY_DICT_INIT; }); diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index adb120fc21..002cc68a3b 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -283,7 +283,7 @@ static void set_string_option_global(vimoption_T *opt, char **varp) /// Set a string option to a new value (without checking the effect). /// The string is copied into allocated memory. -/// if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used. +/// if ("opt_idx" == kOptInvalid) "name" is used, otherwise "opt_idx" is used. /// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When /// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to /// "set_sid". @@ -291,7 +291,7 @@ static void set_string_option_global(vimoption_T *opt, char **varp) /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL. /// /// TODO(famiu): Remove this and its win/buf variants. -void set_string_option_direct(int opt_idx, const char *val, int opt_flags, int set_sid) +void set_string_option_direct(OptIndex opt_idx, const char *val, int opt_flags, int set_sid) { vimoption_T *opt = get_option(opt_idx); @@ -339,7 +339,7 @@ void set_string_option_direct(int opt_idx, const char *val, int opt_flags, int s /// Like set_string_option_direct(), but for a window-local option in "wp". /// Blocks autocommands to avoid the old curwin becoming invalid. -void set_string_option_direct_in_win(win_T *wp, int opt_idx, const char *val, int opt_flags, +void set_string_option_direct_in_win(win_T *wp, OptIndex opt_idx, const char *val, int opt_flags, int set_sid) { win_T *save_curwin = curwin; @@ -355,7 +355,7 @@ void set_string_option_direct_in_win(win_T *wp, int opt_idx, const char *val, in /// Like set_string_option_direct(), but for a buffer-local option in "buf". /// Blocks autocommands to avoid the old curwin becoming invalid. -void set_string_option_direct_in_buf(buf_T *buf, int opt_idx, const char *val, int opt_flags, +void set_string_option_direct_in_buf(buf_T *buf, OptIndex opt_idx, const char *val, int opt_flags, int set_sid) { buf_T *save_curbuf = curbuf; diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 87409bb5db..c7d9a65b86 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -296,7 +296,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) char buf[MAXPATHL]; char transbuf[MAXPATHL]; char *stl; - int opt_idx = -1; + OptIndex opt_idx = kOptInvalid; int opt_scope = 0; stl_hlrec_t *hltab; StlClickRecord *tabtab; @@ -922,9 +922,9 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * /// @param stcp Status column attributes (can be NULL) /// /// @return The final width of the statusline -int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int opt_idx, int opt_scope, - int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab, - statuscol_T *stcp) +int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex opt_idx, + int opt_scope, int fillchar, int maxwidth, stl_hlrec_t **hltab, + StlClickRecord **tabtab, statuscol_T *stcp) { static size_t stl_items_len = 20; // Initial value, grows as needed. static stl_item_t *stl_items = NULL; @@ -958,8 +958,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int opt_idx } // If "fmt" was set insecurely it needs to be evaluated in the sandbox. - // "opt_idx" will be -1 when caller is nvim_eval_statusline(). - const int use_sandbox = (opt_idx != -1) ? was_set_insecurely(wp, opt_idx, opt_scope) : false; + // "opt_idx" will be kOptInvalid when caller is nvim_eval_statusline(). + const int use_sandbox = (opt_idx != kOptInvalid) ? was_set_insecurely(wp, opt_idx, opt_scope) + : false; // When the format starts with "%!" then evaluate it as an expression and // use the result as the actual format string. @@ -1544,7 +1545,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int opt_idx break; case STL_SHOWCMD: - if (p_sc && (opt_idx == -1 || findoption(p_sloc) == opt_idx)) { + if (p_sc && (opt_idx == kOptInvalid || findoption(p_sloc) == opt_idx)) { str = showcmd_buf; } break; @@ -2176,7 +2177,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int opt_idx // TODO(Bram): find out why using called_emsg_before makes tests fail, does it // matter? // if (called_emsg > called_emsg_before) - if (opt_idx != -1 && did_emsg > did_emsg_before) { + if (opt_idx != kOptInvalid && did_emsg > did_emsg_before) { set_string_option_direct(opt_idx, "", OPT_FREE | opt_scope, SID_ERROR); } -- cgit From 8be24fed8ffac51aa4808786ab010e8b87070324 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 7 Dec 2023 13:49:02 +0100 Subject: build: remove config-specific find_package search for libuv Having two separate find_package calls makes it harder to maintain. --- src/nvim/CMakeLists.txt | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 0cdce539eb..51f68886aa 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -11,17 +11,9 @@ set_target_properties(nvim #------------------------------------------------------------------------------- add_library(libuv INTERFACE) -find_package(libuv CONFIG QUIET) -if(TARGET libuv::uv_a) - target_link_libraries(libuv INTERFACE libuv::uv_a) - mark_as_advanced(libuv_DIR) -else() - # Fall back to find module for libuv versions older than v1.45.0 which don't - # provide a config file - find_package(Libuv 1.28.0 REQUIRED MODULE) - target_include_directories(libuv SYSTEM BEFORE INTERFACE ${LIBUV_INCLUDE_DIR}) - target_link_libraries(libuv INTERFACE ${LIBUV_LIBRARIES}) -endif() +find_package(Libuv 1.28.0 REQUIRED) +target_include_directories(libuv SYSTEM BEFORE INTERFACE ${LIBUV_INCLUDE_DIR}) +target_link_libraries(libuv INTERFACE ${LIBUV_LIBRARIES}) add_library(nlua0 MODULE) if(WIN32) -- cgit From a34cc1a44de75eff4c6b43f983dc983eb283119d Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 8 Dec 2023 12:36:37 +0600 Subject: refactor(options): define `kOptIndexCount` Add a macro to indicate the option count so that we can iterate through the options[] table more clearly. This also removes the need for having an option with NULL fullname at the end of `options[]`. --- src/nvim/generators/gen_options.lua | 11 +-- src/nvim/option.c | 129 +++++++++++++++++++----------------- 2 files changed, 77 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 7c5fc08129..b7356a7bb1 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -44,8 +44,8 @@ local list_flags = { --- @param s string --- @return string -local title_case = function(s) - return s:sub(1, 1):upper() .. s:sub(2):lower() +local lowercase_to_titlecase = function(s) + return s:sub(1, 1):upper() .. s:sub(2) end --- @param o vim.option_meta @@ -229,7 +229,6 @@ static vimoption_T options[] = {]]) for i, o in ipairs(options.options) do dump_option(i, o) end -w(' [' .. ('%u'):format(#options.options) .. ']={.fullname=NULL}') w('};') w('') @@ -242,9 +241,13 @@ opt_fd = assert(io.open(options_enum_file, 'w')) w('typedef enum {') w(' kOptInvalid = -1,') + for i, o in ipairs(options.options) do - w((' kOpt%s = %u,'):format(title_case(o.full_name), i - 1)) + w((' kOpt%s = %u,'):format(lowercase_to_titlecase(o.full_name), i - 1)) end + +w(' // Option count, used when iterating through options') +w('#define kOptIndexCount ' .. tostring(#options.options)) w('} OptIndex;') opt_fd:close() diff --git a/src/nvim/option.c b/src/nvim/option.c index cf469d6e5e..6aa22c19af 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -288,7 +288,7 @@ static void set_init_default_cdpath(void) /// default. static void set_init_expand_env(void) { - for (OptIndex opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { vimoption_T *opt = &options[opt_idx]; if (opt->flags & P_NO_DEF_EXP) { continue; @@ -487,9 +487,9 @@ static void set_option_default(const OptIndex opt_idx, int opt_flags) /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL static void set_options_default(int opt_flags) { - for (int i = 0; options[i].fullname; i++) { - if (!(options[i].flags & P_NODEFAULT)) { - set_option_default(i, opt_flags); + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { + if (!(options[opt_idx].flags & P_NODEFAULT)) { + set_option_default(opt_idx, opt_flags); } } @@ -567,18 +567,18 @@ void set_number_default(OptIndex opt_idx, OptInt val) /// Free all options. void free_all_options(void) { - for (int i = 0; options[i].fullname; i++) { - if (options[i].indir == PV_NONE) { + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { + if (options[opt_idx].indir == PV_NONE) { // global option: free value and default value. - if ((options[i].flags & P_ALLOCED) && options[i].var != NULL) { - optval_free(optval_from_varp(i, options[i].var)); + if ((options[opt_idx].flags & P_ALLOCED) && options[opt_idx].var != NULL) { + optval_free(optval_from_varp(opt_idx, options[opt_idx].var)); } - if (options[i].flags & P_DEF_ALLOCED) { - optval_free(optval_from_varp(i, &options[i].def_val)); + if (options[opt_idx].flags & P_DEF_ALLOCED) { + optval_free(optval_from_varp(opt_idx, &options[opt_idx].def_val)); } - } else if (options[i].var != VAR_WIN) { + } else if (options[opt_idx].var != VAR_WIN) { // buffer-local option: free global value - optval_free(optval_from_varp(i, options[i].var)); + optval_free(optval_from_varp(opt_idx, options[opt_idx].var)); } } free_operatorfunc_option(); @@ -1689,7 +1689,7 @@ static void didset_options2(void) /// Check for string options that are NULL (normally only termcap options). void check_options(void) { - for (OptIndex opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++) { + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL) { check_string_option((char **)get_varp(&(options[opt_idx]))); } @@ -3024,7 +3024,9 @@ OptIndex findoption_len(const char *const arg, const size_t len) // letter. There are 26 letters, plus the first "t_" option. if (quick_tab[1] == 0) { const char *p = options[0].fullname; - for (uint16_t i = 1; (s = options[i].fullname) != NULL; i++) { + for (OptIndex i = 1; i < kOptIndexCount; i++) { + s = options[i].fullname; + if (s[0] != p[0]) { if (s[0] == 't' && s[1] == '_') { quick_tab[26] = i; @@ -3049,26 +3051,30 @@ OptIndex findoption_len(const char *const arg, const size_t len) opt_idx = quick_tab[CHAR_ORD_LOW(arg[0])]; } // Match full name - for (; (s = options[opt_idx].fullname) != NULL && s[0] == arg[0]; opt_idx++) { + for (; opt_idx < kOptIndexCount; opt_idx++) { + s = options[opt_idx].fullname; + + // Break if first character no longer matches. + if (s[0] != arg[0]) { + opt_idx = kOptIndexCount; + break; + } + if (strncmp(arg, s, len) == 0 && s[len] == NUL) { break; } } - if (s != NULL && s[0] != arg[0]) { - s = NULL; - } - if (s == NULL && !is_term_opt) { + if (opt_idx == kOptIndexCount && !is_term_opt) { opt_idx = quick_tab[CHAR_ORD_LOW(arg[0])]; // Match short name - for (; options[opt_idx].fullname != NULL; opt_idx++) { + for (; opt_idx < kOptIndexCount; opt_idx++) { s = options[opt_idx].shortname; if (s != NULL && strncmp(arg, s, len) == 0 && s[len] == NUL) { break; } - s = NULL; } } - if (s == NULL) { + if (opt_idx == kOptIndexCount) { opt_idx = kOptInvalid; } else { // Nvim: handle option aliases. @@ -3921,33 +3927,35 @@ static void showoptions(bool all, int opt_flags) for (int run = 1; run <= 2 && !got_int; run++) { // collect the items in items[] int item_count = 0; - for (vimoption_T *p = &options[0]; p->fullname != NULL; p++) { + vimoption_T *opt; + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { + opt = &options[opt_idx]; // apply :filter /pat/ - if (message_filtered(p->fullname)) { + if (message_filtered(opt->fullname)) { continue; } void *varp = NULL; if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) { - if (p->indir != PV_NONE) { - varp = get_varp_scope(p, opt_flags); + if (opt->indir != PV_NONE) { + varp = get_varp_scope(opt, opt_flags); } } else { - varp = get_varp(p); + varp = get_varp(opt); } - if (varp != NULL && (all || !optval_default(p, varp))) { + if (varp != NULL && (all || !optval_default(opt, varp))) { int len; if (opt_flags & OPT_ONECOLUMN) { len = Columns; - } else if (p->flags & P_BOOL) { + } else if (opt->flags & P_BOOL) { len = 1; // a toggle option fits always } else { - option_value2string(p, opt_flags); - len = (int)strlen(p->fullname) + vim_strsize(NameBuff) + 1; + option_value2string(opt, opt_flags); + len = (int)strlen(opt->fullname) + vim_strsize(NameBuff) + 1; } if ((len <= INC - GAP && run == 1) || (len > INC - GAP && run == 2)) { - items[item_count++] = p; + items[item_count++] = opt; } } } @@ -4004,7 +4012,7 @@ static int optval_default(vimoption_T *p, const void *varp) /// Send update to UIs with values of UI relevant options void ui_refresh_options(void) { - for (OptIndex opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { uint32_t flags = options[opt_idx].flags; if (!(flags & P_UI_OPTION)) { continue; @@ -4091,39 +4099,42 @@ int makeset(FILE *fd, int opt_flags, int local_only) // Do the loop over "options[]" twice: once for options with the // P_PRI_MKRC flag and once without. for (int pri = 1; pri >= 0; pri--) { - for (vimoption_T *p = &options[0]; p->fullname; p++) { - if (!(p->flags & P_NO_MKRC) - && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0))) { + vimoption_T *opt; + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { + opt = &options[opt_idx]; + + if (!(opt->flags & P_NO_MKRC) + && ((pri == 1) == ((opt->flags & P_PRI_MKRC) != 0))) { // skip global option when only doing locals - if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL)) { + if (opt->indir == PV_NONE && !(opt_flags & OPT_GLOBAL)) { continue; } // Do not store options like 'bufhidden' and 'syntax' in a vimrc // file, they are always buffer-specific. - if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB)) { + if ((opt_flags & OPT_GLOBAL) && (opt->flags & P_NOGLOB)) { continue; } - void *varp = get_varp_scope(p, opt_flags); // currently used value + void *varp = get_varp_scope(opt, opt_flags); // currently used value // Hidden options are never written. if (!varp) { continue; } // Global values are only written when not at the default value. - if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp)) { + if ((opt_flags & OPT_GLOBAL) && optval_default(opt, varp)) { continue; } if ((opt_flags & OPT_SKIPRTP) - && (p->var == &p_rtp || p->var == &p_pp)) { + && (opt->var == &p_rtp || opt->var == &p_pp)) { continue; } int round = 2; void *varp_local = NULL; // fresh value - if (p->indir != PV_NONE) { - if (p->var == VAR_WIN) { + if (opt->indir != PV_NONE) { + if (opt->var == VAR_WIN) { // skip window-local option when only doing globals if (!(opt_flags & OPT_LOCAL)) { continue; @@ -4131,8 +4142,8 @@ int makeset(FILE *fd, int opt_flags, int local_only) // When fresh value of window-local option is not at the // default, need to write it too. if (!(opt_flags & OPT_GLOBAL) && !local_only) { - void *varp_fresh = get_varp_scope(p, OPT_GLOBAL); // local value - if (!optval_default(p, varp_fresh)) { + void *varp_fresh = get_varp_scope(opt, OPT_GLOBAL); // local value + if (!optval_default(opt, varp_fresh)) { round = 1; varp_local = varp; varp = varp_fresh; @@ -4151,12 +4162,12 @@ int makeset(FILE *fd, int opt_flags, int local_only) cmd = "setlocal"; } - if (p->flags & P_BOOL) { - if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL) { + if (opt->flags & P_BOOL) { + if (put_setbool(fd, cmd, opt->fullname, *(int *)varp) == FAIL) { return FAIL; } - } else if (p->flags & P_NUM) { - if (put_setnum(fd, cmd, p->fullname, (OptInt *)varp) == FAIL) { + } else if (opt->flags & P_NUM) { + if (put_setnum(fd, cmd, opt->fullname, (OptInt *)varp) == FAIL) { return FAIL; } } else { // P_STRING @@ -4164,15 +4175,15 @@ int makeset(FILE *fd, int opt_flags, int local_only) // Don't set 'syntax' and 'filetype' again if the value is // already right, avoids reloading the syntax file. - if (p->indir == PV_SYN || p->indir == PV_FT) { - if (fprintf(fd, "if &%s != '%s'", p->fullname, + if (opt->indir == PV_SYN || opt->indir == PV_FT) { + if (fprintf(fd, "if &%s != '%s'", opt->fullname, *(char **)(varp)) < 0 || put_eol(fd) < 0) { return FAIL; } do_endif = true; } - if (put_setstring(fd, cmd, p->fullname, (char **)varp, p->flags) == FAIL) { + if (put_setstring(fd, cmd, opt->fullname, (char **)varp, opt->flags) == FAIL) { return FAIL; } if (do_endif) { @@ -4862,7 +4873,7 @@ static void init_buf_opt_idx(void) return; } did_init_buf_opt_idx = true; - for (OptIndex i = 0; options[i].fullname != NULL; i++) { + for (OptIndex i = 0; i < kOptIndexCount; i++) { if (options[i].indir & PV_BUF) { buf_opt_idx[options[i].indir & PV_MASK] = i; } @@ -5477,8 +5488,8 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char *fuzzystr, int *numM } } char *str; - for (size_t opt_idx = 0; (str = options[opt_idx].fullname) != NULL; - opt_idx++) { + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { + str = options[opt_idx].fullname; if (options[opt_idx].var == NULL) { continue; } @@ -6136,7 +6147,7 @@ dict_T *get_winbuf_options(const int bufopt) { dict_T *const d = tv_dict_alloc(); - for (OptIndex opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { struct vimoption *opt = &options[opt_idx]; if ((bufopt && (opt->indir & PV_BUF)) @@ -6191,9 +6202,9 @@ Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Error * Dictionary get_all_vimoptions(void) { Dictionary retval = ARRAY_DICT_INIT; - for (size_t i = 0; options[i].fullname != NULL; i++) { - Dictionary opt_dict = vimoption2dict(&options[i], OPT_GLOBAL, curbuf, curwin); - PUT(retval, options[i].fullname, DICTIONARY_OBJ(opt_dict)); + for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { + Dictionary opt_dict = vimoption2dict(&options[opt_idx], OPT_GLOBAL, curbuf, curwin); + PUT(retval, options[opt_idx].fullname, DICTIONARY_OBJ(opt_dict)); } return retval; } -- cgit From 6d698c86d0bd27705d425f973e7da59da5dc83b7 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Mon, 11 Dec 2023 17:16:35 +0100 Subject: fix(coverity): unhandled retval for marktree_itr_get_overlap() #26518 buf_signcols_validate_range() is only called in a buffer with signs, in which the marktree is thus non-empty. Also remove a redundant comment, condition and variable. *** CID 470331: Error handling issues (CHECKED_RETURN) /src/nvim/decoration.c: 824 in buf_signcols_validate_range() 818 819 // Allocate an array of integers holding the overlapping signs in the range. 820 assert(row2 >= row1); 821 int *overlap = xcalloc(sizeof(int), (size_t)(row2 + 1 - row1)); 822 823 // First find the number of overlapping signs at "row1". >>> CID 470331: Error handling issues (CHECKED_RETURN) >>> Calling "marktree_itr_get_overlap" without checking return value (as is done elsewhere 4 out of 5 times). 824 marktree_itr_get_overlap(buf->b_marktree, currow, 0, itr); 825 while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) { 826 if (!mt_invalid(pair.start) && pair.start.flags & MT_FLAG_DECOR_SIGNTEXT) { 827 overlap[0]++; 828 } 829 } --- src/nvim/decoration.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 62cbd33186..74056b7c26 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -719,7 +719,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[], int *cul_id, int *num_id) { MarkTreeIter itr[1]; - if (!buf->b_signs || !marktree_itr_get_overlap(buf->b_marktree, row, 0, itr)) { + if (!marktree_itr_get_overlap(buf->b_marktree, row, 0, itr)) { return; } @@ -815,7 +815,6 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) return; // max signs were removed from the range, no need to count. } - int count = 0; // Number of signs on the current row int currow = row1; MTPair pair = { 0 }; MarkTreeIter itr[1]; @@ -825,15 +824,14 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) int *overlap = xcalloc(sizeof(int), (size_t)(row2 + 1 - row1)); // First find the number of overlapping signs at "row1". - marktree_itr_get_overlap(buf->b_marktree, currow, 0, itr); + (void)marktree_itr_get_overlap(buf->b_marktree, currow, 0, itr); while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) { if (!mt_invalid(pair.start) && pair.start.flags & MT_FLAG_DECOR_SIGNTEXT) { overlap[0]++; } } - // Continue traversing the marktree until beyond "row2". Increment "count" for - // the start of a mark, increment the overlap array until the end of a paired mark. + // Continue traversing the marktree until beyond "row2". while (itr->x) { MTKey mark = marktree_itr_current(itr); if (mark.pos.row > row2) { @@ -841,25 +839,20 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) } // Finish the count at the previous row. if (mark.pos.row != currow) { - buf_signcols_validate_row(buf, count + overlap[currow - row1], add); + buf_signcols_validate_row(buf, overlap[currow - row1], add); currow = mark.pos.row; - count = 0; } - - // Increment count and overlap array for the range of a paired sign mark. + // Increment overlap array for the start and range of a paired sign mark. if (!mt_invalid(mark) && !mt_end(mark) && (mark.flags & MT_FLAG_DECOR_SIGNTEXT)) { - count++; - if (mt_paired(mark)) { - MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL); - for (int i = mark.pos.row + 1; i <= MIN(row2, end.row); i++) { - overlap[i - row1]++; - } + MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL); + for (int i = currow; i <= MIN(row2, end.row < 0 ? currow : end.row); i++) { + overlap[i - row1]++; } } marktree_itr_next(buf->b_marktree, itr); } - buf_signcols_validate_row(buf, count + overlap[currow - row1], add); + buf_signcols_validate_row(buf, overlap[currow - row1], add); xfree(overlap); } -- cgit From b76cc974b9a5dd206f01872f78e6346e54fb5170 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 12 Dec 2023 09:44:46 +0800 Subject: fix(tui): don't forget to update cursor visibility (#26523) --- src/nvim/tui/tui.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index eac59eacac..70df1464ed 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -2255,6 +2255,11 @@ static void augment_terminfo(TUIData *tui, const char *term, int vte_version, in } } +static bool should_invisible(TUIData *tui) +{ + return tui->busy || tui->want_invisible; +} + /// Write the sequence to begin flushing output to `buf`. /// If 'termsync' is set and the terminal supports synchronized output, begin synchronized update. /// Otherwise, hide the cursor to avoid cursor jumping. @@ -2298,11 +2303,10 @@ static size_t flush_buf_end(TUIData *tui, char *buf, size_t len) } const char *str = NULL; - bool should_invisible = tui->busy || tui->want_invisible; - if (tui->is_invisible && !should_invisible) { + if (tui->is_invisible && !should_invisible(tui)) { str = unibi_get_str(tui->ut, unibi_cursor_normal); tui->is_invisible = false; - } else if (!tui->is_invisible && should_invisible) { + } else if (!tui->is_invisible && should_invisible(tui)) { str = unibi_get_str(tui->ut, unibi_cursor_invisible); tui->is_invisible = true; } @@ -2322,7 +2326,7 @@ static void flush_buf(TUIData *tui) char pre[32]; char post[32]; - if (tui->bufpos <= 0) { + if (tui->bufpos <= 0 && tui->is_invisible == should_invisible(tui)) { return; } -- cgit From 2d33a766a17b7304686fc00eec2b2e0ce49400ba Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Tue, 12 Dec 2023 12:08:25 +0900 Subject: fix(extmarks): `U` changed_bytes after extmark_splice (#26501) See also: https://github.com/neovim/neovim/pull/26364 --- src/nvim/undo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 928dd2967c..fd3bb41de0 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -3031,9 +3031,9 @@ void u_undoline(void) char *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); extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum - 1, 0, (colnr_T)strlen(oldp), (colnr_T)strlen(curbuf->b_u_line_ptr), kExtmarkUndo); + changed_bytes(curbuf->b_u_line_lnum, 0); xfree(curbuf->b_u_line_ptr); curbuf->b_u_line_ptr = oldp; -- cgit From d95e3a4c9c8f468158a1f1f23921ebbaae75cf8b Mon Sep 17 00:00:00 2001 From: glepnir Date: Sat, 9 Dec 2023 17:28:28 +0800 Subject: fix: use no_ff instead of ffdos as condition Problem: line2byte behavior is changed after commit b051b13. It no longer return `-1` on empty buffer. Solution: use `nof_ff` instead of `!ff_dos` as condition. Then compatible behavior of line2byte() is restored. --- src/nvim/memline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 5e768839ba..709c7f3d40 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -3907,7 +3907,7 @@ int ml_find_line_or_offset(buf_T *buf, linenr_T lnum, int *offp, bool no_ff) || lnum < 0) { // memline is currently empty. Although if it is loaded, // it behaves like there is one empty line. - if (!ffdos && buf->b_ml.ml_mfp && (lnum == 1 || lnum == 2)) { + if (no_ff && buf->b_ml.ml_mfp && (lnum == 1 || lnum == 2)) { return lnum - 1; } return -1; -- cgit From 1d4a5cd18537d054a564ff19b9361120597d9dd7 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 12 Dec 2023 19:06:22 +0800 Subject: feat(eval): exists() function supports checking v:lua functions (#26485) Problem: Vimscript function exists() can't check v:lua functions. Solution: Add support for v:lua functions to exists(). --- src/nvim/eval/funcs.c | 2 ++ src/nvim/lua/executor.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index c35e0b2ada..1468c5564e 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -1716,6 +1716,8 @@ static void f_exists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } else { n = au_exists(p + 1); } + } else if (strncmp(p, "v:lua.", 6) == 0 && nlua_func_exists(p + 6)) { + n = true; } else { // Internal variable. n = var_exists(p); } diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index e665732c1a..e0bdbbc1e9 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -2313,3 +2313,21 @@ void nlua_init_defaults(void) os_errmsg("\n"); } } + +/// check lua function exist +bool nlua_func_exists(const char *lua_funcname) +{ + MAXSIZE_TEMP_ARRAY(args, 1); + size_t length = strlen(lua_funcname) + 8; + char *str = xmalloc(length); + vim_snprintf(str, length, "return %s", lua_funcname); + ADD_C(args, CSTR_AS_OBJ(str)); + Error err = ERROR_INIT; + Object result = NLUA_EXEC_STATIC("return type(loadstring(...)()) =='function'", args, &err); + xfree(str); + + if (result.type != kObjectTypeBoolean) { + return false; + } + return result.data.boolean; +} -- cgit From b40170f7a3ca4bd157eeb52c9d57cb2ebfe3c562 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 12 Dec 2023 20:34:02 +0800 Subject: fix(lua): memory leak when using invalid syntax with exists() (#26530) --- src/nvim/lua/executor.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index e0bdbbc1e9..0763bbd329 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -2323,10 +2323,12 @@ bool nlua_func_exists(const char *lua_funcname) vim_snprintf(str, length, "return %s", lua_funcname); ADD_C(args, CSTR_AS_OBJ(str)); Error err = ERROR_INIT; - Object result = NLUA_EXEC_STATIC("return type(loadstring(...)()) =='function'", args, &err); + Object result = NLUA_EXEC_STATIC("return type(loadstring(...)()) == 'function'", args, &err); xfree(str); + api_clear_error(&err); if (result.type != kObjectTypeBoolean) { + api_free_object(result); return false; } return result.data.boolean; -- cgit From 1907abb4c27857fe7f4e7394f32e130f9955a2e7 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Tue, 12 Dec 2023 13:19:46 -0600 Subject: fix(stream): do not close handle if it is already closing (#26537) uv_close asserts that a handle is not already closing. We can guard against this assertion failure by manually checking the handle's closing status ourselves. --- src/nvim/event/stream.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 17c1b0a072..8baecbbb31 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -128,15 +128,22 @@ void stream_may_close(Stream *stream) void stream_close_handle(Stream *stream) FUNC_ATTR_NONNULL_ALL { + uv_handle_t *handle = NULL; if (stream->uvstream) { if (uv_stream_get_write_queue_size(stream->uvstream) > 0) { WLOG("closed Stream (%p) with %zu unwritten bytes", (void *)stream, uv_stream_get_write_queue_size(stream->uvstream)); } - uv_close((uv_handle_t *)stream->uvstream, close_cb); + handle = (uv_handle_t *)stream->uvstream; } else { - uv_close((uv_handle_t *)&stream->uv.idle, close_cb); + handle = (uv_handle_t *)&stream->uv.idle; + } + + assert(handle != NULL); + + if (!uv_is_closing(handle)) { + uv_close(handle, close_cb); } } -- cgit From d65c6a0bafada059e87a11a4bcd129afc16d2e5d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 13 Dec 2023 06:17:50 +0800 Subject: vim-patch:9.0.2159: screenpos() may crash with neg. column (#26542) Problem: screenpos() may crash with neg. column Solution: validate and correct column closes: vim/vim#13669 https://github.com/vim/vim/commit/ec54af4e26952d954a4cc009f62c80ea01445d30 --- src/nvim/move.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/move.c b/src/nvim/move.c index 12fb7d1f82..bbc3d792c0 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1125,6 +1125,9 @@ void f_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) semsg(_(e_invalid_line_number_nr), pos.lnum); return; } + if (pos.col < 0) { + pos.col = 0; + } int row = 0; int scol = 0, ccol = 0, ecol = 0; textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol, false); -- cgit From c8223007d0e0a1d5dbcda31f364d1d1baee9d772 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 13 Dec 2023 11:11:49 +0100 Subject: docs: add code-overview from wiki to src/nvim/README.md --- src/nvim/README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'src') diff --git a/src/nvim/README.md b/src/nvim/README.md index b484d59cb3..b264c918b6 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -392,6 +392,68 @@ modes managed by the `state_enter` loop: - insert mode: `insert_{enter,check,execute}()`(`edit.c`) - terminal mode: `terminal_{enter,execute}()`(`terminal.c`) +## Important variables + +The current mode is stored in `State`. The values it can have are `MODE_NORMAL`, +`MODE_INSERT`, `MODE_CMDLINE`, and a few others. + +The current window is `curwin`. The current buffer is `curbuf`. These point +to structures with the cursor position in the window, option values, the file +name, etc. + +All the global variables are declared in `globals.h`. + +### The main loop + +The main loop is implemented in state_enter. The basic idea is that Vim waits +for the user to type a character and processes it until another character is +needed. Thus there are several places where Vim waits for a character to be +typed. The `vgetc()` function is used for this. It also handles mapping. + +Updating the screen is mostly postponed until a command or a sequence of +commands has finished. The work is done by `update_screen()`, which calls +`win_update()` for every window, which calls `win_line()` for every line. +See the start of [drawscreen.c](drawscreen.c) for more explanations. + +### Command-line mode + +When typing a `:`, `normal_cmd()` will call `getcmdline()` to obtain a line with +an Ex command. `getcmdline()` calls a loop that will handle each typed +character. It returns when hitting `` or `` or some other character that +ends the command line mode. + +### Ex commands + +Ex commands are handled by the function `do_cmdline()`. It does the generic +parsing of the `:` command line and calls `do_one_cmd()` for each separate +command. It also takes care of while loops. + +`do_one_cmd()` parses the range and generic arguments and puts them in the +exarg_t and passes it to the function that handles the command. + +The `:` commands are listed in [ex_cmds.lua](ex_cmds.lua). + +### Normal mode commands + +The Normal mode commands are handled by the `normal_cmd()` function. It also +handles the optional count and an extra character for some commands. These +are passed in a `cmdarg_T` to the function that handles the command. + +There is a table `nv_cmds` in [normal.c](normal.c) which +lists the first character of every +command. The second entry of each item is the name of the function that +handles the command. + +### Insert mode commands + +When doing an `i` or `a` command, `normal_cmd()` will call the `edit()` function. +It contains a loop that waits for the next character and handles it. It +returns when leaving Insert mode. + +### Options + +There is a list with all option names in [options.lua](options.lua). + Async event support ------------------- -- cgit From 1d63a057a6cb47e84c204f64ba5406cfe7a3ab93 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 13 Dec 2023 19:16:41 +0100 Subject: docs: fix links --- src/clint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index ed5aaf43d2..021d6b0a16 100755 --- a/src/clint.py +++ b/src/clint.py @@ -2082,7 +2082,7 @@ def CheckLanguage(filename, clean_lines, linenum, error): if match: error(filename, linenum, 'runtime/deprecated', 4, 'Accessing list_T internals directly is prohibited; ' - 'see https://github.com/neovim/neovim/wiki/List-management-in-Neovim') + 'see https://neovim.io/doc/user/dev_vimpatch.html#dev-vimpatch-list-management') # Check for suspicious usage of "if" like # } if (a == b) { -- cgit From 846714ca3e70f8e72533b73fc67fc159e0a9e606 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 14 Dec 2023 09:32:05 +0800 Subject: fix(tui): don't use tui->params[] for 'termsync' (#26565) Problem: 'termsync' overwrites the first parameter of a format string when UNIBI_OUT() encounters an overflow. Solution: Don't use tui->params[] for 'termsync'. --- src/nvim/tui/tui.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 70df1464ed..f084ab212b 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -2269,10 +2269,11 @@ static bool should_invisible(TUIData *tui) static size_t flush_buf_start(TUIData *tui, char *buf, size_t len) FUNC_ATTR_NONNULL_ALL { - const char *str = NULL; + unibi_var_t params[9]; // Don't use tui->params[] as they may already be in use. + const char *str = NULL; if (tui->sync_output && tui->unibi_ext.sync != -1) { - UNIBI_SET_NUM_VAR(tui->params[0], 1); + UNIBI_SET_NUM_VAR(params[0], 1); str = unibi_get_ext_str(tui->ut, (size_t)tui->unibi_ext.sync); } else if (!tui->is_invisible) { str = unibi_get_str(tui->ut, unibi_cursor_invisible); @@ -2283,7 +2284,7 @@ static size_t flush_buf_start(TUIData *tui, char *buf, size_t len) return 0; } - return unibi_run(str, tui->params, buf, len); + return unibi_run(str, params, buf, len); } /// Write the sequence to end flushing output to `buf`. @@ -2295,11 +2296,13 @@ static size_t flush_buf_start(TUIData *tui, char *buf, size_t len) static size_t flush_buf_end(TUIData *tui, char *buf, size_t len) FUNC_ATTR_NONNULL_ALL { + unibi_var_t params[9]; // Don't use tui->params[] as they may already be in use. + size_t offset = 0; if (tui->sync_output && tui->unibi_ext.sync != -1) { - UNIBI_SET_NUM_VAR(tui->params[0], 0); + UNIBI_SET_NUM_VAR(params[0], 0); const char *str = unibi_get_ext_str(tui->ut, (size_t)tui->unibi_ext.sync); - offset = unibi_run(str, tui->params, buf, len); + offset = unibi_run(str, params, buf, len); } const char *str = NULL; @@ -2313,7 +2316,7 @@ static size_t flush_buf_end(TUIData *tui, char *buf, size_t len) if (str != NULL) { assert(len >= offset); - offset += unibi_run(str, tui->params, buf + offset, len - offset); + offset += unibi_run(str, params, buf + offset, len - offset); } return offset; -- cgit From 619407eb548c7df56bc99b945338e9446f846fbb Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 14 Dec 2023 16:08:00 +0800 Subject: feat(nvim_open_term): convert LF => CRLF (#26384) Problem: Unlike termopen(), nvim_open_term() PTYs do not carriage-return the cursor on newline ("\n") input. nvim --clean :let chan_id = nvim_open_term(1, {}) :call chansend(chan_id, ["here", "are", "some", "lines"]) Actual behavior: here are some lines Expected behaviour: here are some lines Solution: Add `force_crlf` option, and enable it by default. --- src/nvim/api/keysets_defs.h | 1 + src/nvim/api/vim.c | 3 ++- src/nvim/channel.c | 1 + src/nvim/terminal.c | 18 +++++++++++++++++- src/nvim/terminal.h | 1 + 5 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index d1cbe43de0..c0daa0ca74 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -344,4 +344,5 @@ typedef struct { typedef struct { OptionalKeys is_set__open_term_; LuaRef on_input; + Boolean force_crlf; } Dict(open_term); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a52d7493e3..2f3d527b9e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -985,6 +985,7 @@ fail: /// as a "\r", not as a "\n". |textlock| applies. It is possible /// to call |nvim_chan_send()| directly in the callback however. /// ["input", term, bufnr, data] +/// - force_crlf: (boolean, default true) Convert "\n" to "\r\n". /// @param[out] err Error details, if any /// @return Channel id, or 0 on error Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) @@ -1002,7 +1003,6 @@ Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) } LuaRef cb = LUA_NOREF; - if (HAS_KEY(opts, open_term, on_input)) { cb = opts->on_input; opts->on_input = LUA_NOREF; @@ -1020,6 +1020,7 @@ Integer nvim_open_term(Buffer buffer, Dict(open_term) *opts, Error *err) .write_cb = term_write, .resize_cb = term_resize, .close_cb = term_close, + .force_crlf = GET_BOOL_OR_TRUE(opts, open_term, force_crlf), }; channel_incref(chan); terminal_open(&chan->term, buf, topts); diff --git a/src/nvim/channel.c b/src/nvim/channel.c index ca8cbed8f9..fb4711f7d9 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -801,6 +801,7 @@ void channel_terminal_open(buf_T *buf, Channel *chan) .write_cb = term_write, .resize_cb = term_resize, .close_cb = term_close, + .force_crlf = false, }; buf->b_p_channel = (OptInt)chan->id; // 'channel' option channel_incref(chan); diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index af9693c4b0..3b70ee922a 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -43,6 +43,7 @@ #include #include +#include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" @@ -80,6 +81,7 @@ #include "nvim/optionstr.h" #include "nvim/pos_defs.h" #include "nvim/state.h" +#include "nvim/strings.h" #include "nvim/terminal.h" #include "nvim/types_defs.h" #include "nvim/ui.h" @@ -786,7 +788,21 @@ void terminal_receive(Terminal *term, const char *data, size_t len) return; } - vterm_input_write(term->vt, data, len); + if (term->opts.force_crlf) { + StringBuilder crlf_data = KV_INITIAL_VALUE; + + for (size_t i = 0; i < len; i++) { + if (data[i] == '\n' && (i == 0 || (i > 0 && data[i - 1] != '\r'))) { + kv_push(crlf_data, '\r'); + } + kv_push(crlf_data, data[i]); + } + + vterm_input_write(term->vt, crlf_data.items, kv_size(crlf_data)); + kv_destroy(crlf_data); + } else { + vterm_input_write(term->vt, data, len); + } vterm_screen_flush_damage(term->vts); } diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h index db62bd2a5b..ffa97f17b2 100644 --- a/src/nvim/terminal.h +++ b/src/nvim/terminal.h @@ -16,6 +16,7 @@ typedef struct { terminal_write_cb write_cb; terminal_resize_cb resize_cb; terminal_close_cb close_cb; + bool force_crlf; } TerminalOptions; #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit From 320e9c1c21817fd76b84345018661f70437fa4b5 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Wed, 13 Dec 2023 23:30:19 +0100 Subject: fix(extmark): only invalidate unpaired marks on deleted rows Problem: Unpaired marks are invalidated if its column is deleted, which may just be a "placeholder" column, e.g. for signs. Solution: Only remove unpaired marks if its entire row is deleted. --- src/nvim/extmark.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 92fbc6fb79..f914137ccc 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -332,9 +332,13 @@ void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, coln if (endpos.row < 0) { endpos = mark.pos; } - if ((endpos.col <= u_col || (!u_col && endpos.row == mark.pos.row)) - && mark.pos.col >= l_col - && mark.pos.row >= l_row && endpos.row <= u_row - (u_col ? 0 : 1)) { + // Invalidate unpaired marks in deleted lines and paired marks whose entire + // range has been deleted. + if ((!mt_paired(mark) && mark.pos.row < u_row) + || (mt_paired(mark) + && (endpos.col <= u_col || (!u_col && endpos.row == mark.pos.row)) + && mark.pos.col >= l_col + && mark.pos.row >= l_row && endpos.row <= u_row - (u_col ? 0 : 1))) { if (mt_no_undo(mark)) { extmark_del(buf, itr, mark, true); continue; -- cgit From 3c2c022e5e299ecac4663c3813e2db5e2b099ffa Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 7 Dec 2023 01:34:29 +0600 Subject: refactor(options): remove option type macros Problem: We have `P_(BOOL|NUM|STRING)` macros to represent an option's type, which is redundant because `OptValType` can already do that. The current implementation of option type flags is also too limited to allow adding multitype options in the future. Solution: Remove `P_(BOOL|NUM|STRING)` and replace it with a new `type_flags` attribute in `vimoption_T`. Also do some groundwork for adding multitype options in the future. Side-effects: Attempting to set an invalid keycode option (e.g. `set t_foo=123`) no longer gives an error. --- src/nvim/eval.c | 42 ++-- src/nvim/eval.h | 1 + src/nvim/eval/vars.c | 64 ++--- src/nvim/generators/gen_options.lua | 33 ++- src/nvim/math.c | 26 ++ src/nvim/math.h | 9 + src/nvim/memory.c | 7 + src/nvim/option.c | 486 ++++++++++++++++-------------------- src/nvim/option.h | 61 ++++- src/nvim/option_defs.h | 11 +- src/nvim/option_vars.h | 72 +++--- src/nvim/options.lua | 240 +++++++++--------- 12 files changed, 538 insertions(+), 514 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1fdaa95076..11c6034cc8 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3767,10 +3767,12 @@ int eval_option(const char **const arg, typval_T *const rettv, const bool evalua FUNC_ATTR_NONNULL_ARG(1) { const bool working = (**arg == '+'); // has("+option") + OptIndex opt_idx; int scope; // Isolate the option name and find its value. - char *option_end = (char *)find_option_end(arg, &scope); + char *const option_end = (char *)find_option_var_end(arg, &opt_idx, &scope); + if (option_end == NULL) { if (rettv != NULL) { semsg(_("E112: Option name missing: %s"), *arg); @@ -3783,12 +3785,11 @@ int eval_option(const char **const arg, typval_T *const rettv, const bool evalua return OK; } - int ret = OK; char c = *option_end; *option_end = NUL; + int ret = OK; bool is_tty_opt = is_tty_option(*arg); - OptIndex opt_idx = is_tty_opt ? kOptInvalid : findoption(*arg); if (opt_idx == kOptInvalid && !is_tty_opt) { // Only give error if result is going to be used. @@ -3801,13 +3802,7 @@ int eval_option(const char **const arg, typval_T *const rettv, const bool evalua OptVal value = is_tty_opt ? get_tty_option(*arg) : get_option_value(opt_idx, scope); assert(value.type != kOptValTypeNil); - *rettv = optval_as_tv(value); - - // Convert boolean option value to number for backwards compatibility. - if (rettv->v_type == VAR_BOOL) { - rettv->v_type = VAR_NUMBER; - rettv->vval.v_number = rettv->vval.v_bool == kBoolVarTrue ? 1 : 0; - } + *rettv = optval_as_tv(value, true); } else if (working && !is_tty_opt && is_option_hidden(opt_idx)) { ret = FAIL; } @@ -8138,13 +8133,14 @@ void ex_execute(exarg_T *eap) eap->nextcmd = check_nextcmd(arg); } -/// Skip over the name of an option: "&option", "&g:option" or "&l:option". +/// Skip over the name of an option variable: "&option", "&g:option" or "&l:option". /// -/// @param arg points to the "&" or '+' when called, to "option" when returning. +/// @param[in,out] arg Points to the "&" or '+' when called, to "option" when returning. +/// @param[out] opt_idxp Set to option index in options[] table. +/// @param[out] scope Set to option scope. /// -/// @return NULL when no option name found. Otherwise pointer to the char -/// after the option name. -const char *find_option_end(const char **const arg, int *const scope) +/// @return NULL when no option name found. Otherwise pointer to the char after the option name. +const char *find_option_var_end(const char **const arg, OptIndex *const opt_idxp, int *const scope) { const char *p = *arg; @@ -8159,19 +8155,9 @@ const char *find_option_end(const char **const arg, int *const scope) *scope = 0; } - if (!ASCII_ISALPHA(*p)) { - return NULL; - } - *arg = p; - - if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) { - p += 4; // t_xx/termcap option - } else { - while (ASCII_ISALPHA(*p)) { - p++; - } - } - return p; + const char *end = find_option_end(p, opt_idxp); + *arg = end == NULL ? *arg : p; + return end; } static var_flavour_T var_flavour(char *varname) diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 6d225b2713..65f7020295 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -13,6 +13,7 @@ #include "nvim/hashtab_defs.h" #include "nvim/macros_defs.h" #include "nvim/mbyte_defs.h" // IWYU pragma: keep +#include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/os/fileio_defs.h" // IWYU pragma: keep #include "nvim/os/stdpaths_defs.h" // IWYU pragma: keep #include "nvim/vim_defs.h" // IWYU pragma: keep diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 73c8ae1191..6fd707a0b0 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -761,11 +761,12 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, // Find the end of the name. char *arg_end = NULL; + OptIndex opt_idx; int scope; - char *const p = (char *)find_option_end((const char **)&arg, &scope); - if (p == NULL - || (endchars != NULL - && vim_strchr(endchars, (uint8_t)(*skipwhite(p))) == NULL)) { + + char *const p = (char *)find_option_var_end((const char **)&arg, &opt_idx, &scope); + + if (p == NULL || (endchars != NULL && vim_strchr(endchars, (uint8_t)(*skipwhite(p))) == NULL)) { emsg(_(e_letunexp)); return NULL; } @@ -774,8 +775,6 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, *p = NUL; bool is_tty_opt = is_tty_option(arg); - OptIndex opt_idx = is_tty_opt ? kOptInvalid : findoption(arg); - uint32_t opt_p_flags = get_option_flags(opt_idx); bool hidden = is_option_hidden(opt_idx); OptVal curval = is_tty_opt ? get_tty_option(arg) : get_option_value(opt_idx, scope); OptVal newval = NIL_OPTVAL; @@ -792,7 +791,7 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, } bool error; - newval = tv_to_optval(tv, arg, opt_p_flags, &error); + newval = tv_to_optval(tv, opt_idx, arg, &error); if (error) { goto theend; } @@ -1849,22 +1848,27 @@ static void getwinvar(typval_T *argvars, typval_T *rettv, int off) /// /// @return Typval converted to OptVal. Must be freed by caller. /// Returns NIL_OPTVAL for invalid option name. -static OptVal tv_to_optval(typval_T *tv, const char *option, uint32_t flags, bool *error) +/// +/// TODO(famiu): Refactor this to support multitype options. +static OptVal tv_to_optval(typval_T *tv, OptIndex opt_idx, const char *option, bool *error) { OptVal value = NIL_OPTVAL; char nbuf[NUMBUFLEN]; bool err = false; + const bool is_tty_opt = is_tty_option(option); + const bool option_has_bool = !is_tty_opt && option_has_type(opt_idx, kOptValTypeBoolean); + const bool option_has_num = !is_tty_opt && option_has_type(opt_idx, kOptValTypeNumber); + const bool option_has_str = is_tty_opt || option_has_type(opt_idx, kOptValTypeString); - if ((flags & P_FUNC) && tv_is_func(*tv)) { + if (!is_tty_opt && (get_option(opt_idx)->flags & P_FUNC) && tv_is_func(*tv)) { // If the option can be set to a function reference or a lambda // and the passed value is a function reference, then convert it to // the name (string) of the function reference. char *strval = encode_tv2string(tv, NULL); err = strval == NULL; value = CSTR_AS_OPTVAL(strval); - } else if (flags & (P_NUM | P_BOOL)) { - varnumber_T n = (flags & P_NUM) ? tv_get_number_chk(tv, &err) - : tv_get_bool_chk(tv, &err); + } else if (option_has_bool || option_has_num) { + varnumber_T n = option_has_num ? tv_get_number_chk(tv, &err) : tv_get_bool_chk(tv, &err); // This could be either "0" or a string that's not a number. // So we need to check if it's actually a number. if (!err && tv->v_type == VAR_STRING && n == 0) { @@ -1877,14 +1881,14 @@ static OptVal tv_to_optval(typval_T *tv, const char *option, uint32_t flags, boo semsg(_("E521: Number required: &%s = '%s'"), option, tv->vval.v_string); } } - value = (flags & P_NUM) ? NUMBER_OPTVAL((OptInt)n) : BOOLEAN_OPTVAL(TRISTATE_FROM_INT(n)); - } else if ((flags & P_STRING) || is_tty_option(option)) { + value = option_has_num ? NUMBER_OPTVAL((OptInt)n) : BOOLEAN_OPTVAL(TRISTATE_FROM_INT(n)); + } else if (option_has_str) { // Avoid setting string option to a boolean or a special value. if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) { const char *strval = tv_get_string_buf_chk(tv, nbuf); err = strval == NULL; value = CSTR_TO_OPTVAL(strval); - } else if (flags & P_STRING) { + } else if (!is_tty_opt) { err = true; emsg(_(e_stringreq)); } @@ -1900,10 +1904,12 @@ static OptVal tv_to_optval(typval_T *tv, const char *option, uint32_t flags, boo /// Convert an option value to typval. /// -/// @param[in] value Option value to convert. +/// @param[in] value Option value to convert. +/// @param numbool Whether to convert boolean values to number. +/// Used for backwards compatibility. /// /// @return OptVal converted to typval. -typval_T optval_as_tv(OptVal value) +typval_T optval_as_tv(OptVal value, bool numbool) { typval_T rettv = { .v_type = VAR_SPECIAL, .vval = { .v_special = kSpecialVarNull } }; @@ -1911,19 +1917,16 @@ typval_T optval_as_tv(OptVal value) case kOptValTypeNil: break; case kOptValTypeBoolean: - switch (value.data.boolean) { - case kTrue: - rettv.v_type = VAR_BOOL; - rettv.vval.v_bool = kBoolVarTrue; - break; - case kFalse: - rettv.v_type = VAR_BOOL; - rettv.vval.v_bool = kBoolVarFalse; - break; - case kNone: - break; // return v:null for None boolean value + if (value.data.boolean != kNone) { + if (numbool) { + rettv.v_type = VAR_NUMBER; + rettv.vval.v_number = value.data.boolean == kTrue; + } else { + rettv.v_type = VAR_BOOL; + rettv.vval.v_bool = value.data.boolean == kTrue; + } } - break; + break; // return v:null for None boolean value. case kOptValTypeNumber: rettv.v_type = VAR_NUMBER; rettv.vval.v_number = value.data.number; @@ -1947,8 +1950,7 @@ static void set_option_from_tv(const char *varname, typval_T *varp) } bool error = false; - uint32_t opt_p_flags = get_option_flags(opt_idx); - OptVal value = tv_to_optval(varp, varname, opt_p_flags, &error); + OptVal value = tv_to_optval(varp, opt_idx, varname, &error); if (!error) { const char *errmsg = set_option_value_handle_tty(varname, opt_idx, value, OPT_LOCAL); diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index b7356a7bb1..61d5df3c84 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -16,12 +16,6 @@ local options = require('options') local cstr = options.cstr -local type_flags = { - bool = 'P_BOOL', - number = 'P_NUM', - string = 'P_STRING', -} - local redraw_flags = { ui_option = 'P_UI_OPTION', tabline = 'P_RTABL', @@ -51,11 +45,14 @@ end --- @param o vim.option_meta --- @return string local function get_flags(o) - --- @type string[] - local ret = { type_flags[o.type] } + --- @type string + local flags = '0' + + --- @param f string local add_flag = function(f) - ret[1] = ret[1] .. '|' .. f + flags = flags .. '|' .. f end + if o.list then add_flag(list_flags[o.list]) end @@ -91,7 +88,22 @@ local function get_flags(o) add_flag(def_name) end end - return ret[1] + return flags +end + +--- @param o vim.option_meta +--- @return string +local function get_type_flags(o) + local opt_types = (type(o.type) == 'table') and o.type or { o.type } + local type_flags = '0' + assert(type(opt_types) == 'table') + + for _, opt_type in ipairs(opt_types) do + assert(type(opt_type) == 'string') + type_flags = ('%s | (1 << kOptValType%s)'):format(type_flags, lowercase_to_titlecase(opt_type)) + end + + return type_flags end --- @param c string|string[] @@ -153,6 +165,7 @@ local function dump_option(i, o) w(' .shortname=' .. cstr(o.abbreviation)) end w(' .flags=' .. get_flags(o)) + w(' .type_flags=' .. get_type_flags(o)) if o.enable_if then w(get_cond(o.enable_if)) end diff --git a/src/nvim/math.c b/src/nvim/math.c index 79e0be691b..9a0825823c 100644 --- a/src/nvim/math.c +++ b/src/nvim/math.c @@ -40,3 +40,29 @@ int xisnan(double d) { return FP_NAN == xfpclassify(d); } + +/// Count trailing zeroes at the end of bit field. +int xctz(uint64_t x) +{ + // If x == 0, that means all bits are zeroes. + if (x == 0) { + return 8 * sizeof(x); + } + + // Use compiler builtin if possible. +#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 4)) + return __builtin_ctzll(x); +#else + int count = 0; + // Set x's trailing zeroes to ones and zero the rest. + x = (x ^ (x - 1)) >> 1; + + // Increment count until there are just zero bits remaining. + while (x) { + count++; + x >>= 1; + } + + return count; +#endif +} diff --git a/src/nvim/math.h b/src/nvim/math.h index c88ce1e03d..0321d0c9c6 100644 --- a/src/nvim/math.h +++ b/src/nvim/math.h @@ -1,5 +1,14 @@ #pragma once +#include +#include + +/// Check if number is a power of two +static inline bool is_power_of_two(uint64_t x) +{ + return x != 0 && ((x & (x - 1)) == 0); +} + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "math.h.generated.h" #endif diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 7036c91c9b..a0786391b5 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -515,6 +515,13 @@ bool strequal(const char *a, const char *b) return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0); } +/// Returns true if first `n` characters of strings `a` and `b` are equal. Arguments may be NULL. +bool strnequal(const char *a, const char *b, size_t n) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + return (a == NULL && b == NULL) || (a && b && strncmp(a, b, n) == 0); +} + // Avoid repeating the error message many times (they take 1 second each). // Did_outofmem_msg is reset when a character is read. void do_outofmem_msg(size_t size) diff --git a/src/nvim/option.c b/src/nvim/option.c index 6aa22c19af..1f4f547759 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -108,8 +108,6 @@ static const char e_not_allowed_in_modeline[] = N_("E520: Not allowed in a modeline"); static const char e_not_allowed_in_modeline_when_modelineexpr_is_off[] = N_("E992: Not allowed in a modeline when 'modelineexpr' is off"); -static const char e_key_code_not_set[] - = N_("E846: Key code not set"); static const char e_number_required_after_equal[] = N_("E521: Number required after ="); static const char e_preview_window_already_exists[] @@ -419,7 +417,9 @@ void set_init_1(bool clean_arg) /// Set an option to its default value. /// This does not take care of side effects! /// -/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL +/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL. +/// +/// TODO(famiu): Refactor this when def_val uses OptVal. static void set_option_default(const OptIndex opt_idx, int opt_flags) { int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; @@ -429,7 +429,7 @@ static void set_option_default(const OptIndex opt_idx, int opt_flags) void *varp = get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); uint32_t flags = opt->flags; if (varp != NULL) { // skip hidden option, nothing to do for it - if (flags & P_STRING) { + if (option_has_type(opt_idx, kOptValTypeString)) { // Use set_string_option_direct() for local options to handle freeing and allocating the // value. if (opt->indir != PV_NONE) { @@ -441,7 +441,7 @@ static void set_option_default(const OptIndex opt_idx, int opt_flags) *(char **)varp = opt->def_val; opt->flags &= ~P_ALLOCED; } - } else if (flags & P_NUM) { + } else if (option_has_type(opt_idx, kOptValTypeNumber)) { if (opt->indir == PV_SCROLL) { win_comp_scroll(curwin); } else { @@ -459,7 +459,7 @@ static void set_option_default(const OptIndex opt_idx, int opt_flags) *(OptInt *)get_varp_scope(opt, OPT_GLOBAL) = def_val; } } - } else { // P_BOOL + } else { // boolean *(int *)varp = (int)(intptr_t)opt->def_val; #ifdef UNIX // 'modeline' defaults to off for root @@ -1015,81 +1015,23 @@ static set_prefix_T get_option_prefix(char **argp) return PREFIX_NONE; } -/// @param[in] arg Pointer to start option name -/// @param[out] opt_idxp Option index in options[] table. -/// @param[out] keyp -/// @param[out] len Length of option name -/// @return FAIL if an error is detected, OK otherwise -static int parse_option_name(char *arg, int *keyp, int *lenp, OptIndex *opt_idxp) -{ - // find end of name - int key = 0; - int len; - OptIndex opt_idx; - - if (*arg == '<') { - opt_idx = kOptInvalid; - // look out for ;> - if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4]) { - len = 5; - } else { - len = 1; - while (arg[len] != NUL && arg[len] != '>') { - len++; - } - } - if (arg[len] != '>') { - return FAIL; - } - if (arg[1] == 't' && arg[2] == '_') { // could be term code - opt_idx = findoption_len(arg + 1, (size_t)(len - 1)); - } - len++; - if (opt_idx == kOptInvalid) { - key = find_key_option(arg + 1, true); - } - } else { - // The two characters after "t_" may not be alphanumeric. - if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) { - len = 4; - } else { - len = 0; - while (ASCII_ISALNUM(arg[len]) || arg[len] == '_') { - len++; - } - } - opt_idx = findoption_len(arg, (size_t)len); - if (opt_idx == kOptInvalid) { - key = find_key_option(arg, false); - } - } - - *keyp = key; - *lenp = len; - *opt_idxp = opt_idx; - - return OK; -} - static int validate_opt_idx(win_T *win, OptIndex opt_idx, int opt_flags, uint32_t flags, set_prefix_T prefix, const char **errmsg) { // Only bools can have a prefix of 'inv' or 'no' - if (!(flags & P_BOOL) && prefix != PREFIX_NONE) { + if (!option_has_type(opt_idx, kOptValTypeBoolean) && prefix != PREFIX_NONE) { *errmsg = e_invarg; return FAIL; } // Skip all options that are not window-local (used when showing // an already loaded buffer in a window). - if ((opt_flags & OPT_WINONLY) - && (opt_idx == kOptInvalid || options[opt_idx].var != VAR_WIN)) { + if ((opt_flags & OPT_WINONLY) && (opt_idx == kOptInvalid || options[opt_idx].var != VAR_WIN)) { return FAIL; } // Skip all options that are window-local (used for :vimgrep). - if ((opt_flags & OPT_NOWIN) && opt_idx != kOptInvalid - && options[opt_idx].var == VAR_WIN) { + if ((opt_flags & OPT_NOWIN) && opt_idx != kOptInvalid && options[opt_idx].var == VAR_WIN) { return FAIL; } @@ -1123,6 +1065,77 @@ static int validate_opt_idx(win_T *win, OptIndex opt_idx, int opt_flags, uint32_ return OK; } +/// Skip over the name of a TTY option or keycode option. +/// +/// @param[in] arg Start of TTY or keycode option name. +/// +/// @return NULL when option isn't a TTY or keycode option. Otherwise pointer to the char after the +/// option name. +static const char *find_tty_option_end(const char *arg) +{ + if (strequal(arg, "term")) { + return arg + sizeof("term") - 1; + } else if (strequal(arg, "ttytype")) { + return arg + sizeof("ttytype") - 1; + } + + const char *p = arg; + bool delimit = false; // whether to delimit < + + if (arg[0] == '<') { + // look out for ;> + delimit = true; + p++; + } + if (p[0] == 't' && p[1] == '_' && p[2] && p[3]) { + p += 4; + } else if (delimit) { + // Search for delimiting >. + while (*p != NUL && *p != '>') { + p++; + } + } + // Return NULL when delimiting > is not found. + if (delimit) { + if (*p != '>') { + return NULL; + } + p++; + } + + return arg == p ? NULL : p; +} + +/// Skip over the name of an option. +/// +/// @param[in] arg Start of option name. +/// @param[out] opt_idxp Set to option index in options[] table. +/// +/// @return NULL when no option name found. Otherwise pointer to the char after the option name. +const char *find_option_end(const char *arg, OptIndex *opt_idxp) +{ + const char *p; + + // Handle TTY and keycode options separately. + if ((p = find_tty_option_end(arg)) != NULL) { + *opt_idxp = kOptInvalid; + return p; + } else { + p = arg; + } + + if (!ASCII_ISALPHA(*p)) { + *opt_idxp = kOptInvalid; + return NULL; + } + while (ASCII_ISALPHA(*p)) { + p++; + } + + *opt_idxp = findoption_len(arg, (size_t)(p - arg)); + return p; +} + /// Get new option value from argp. Allocated OptVal must be freed by caller. static OptVal get_option_newval(OptIndex opt_idx, int opt_flags, set_prefix_T prefix, char **argp, int nextchar, set_op_T op, uint32_t flags, void *varp, char *errbuf, @@ -1262,61 +1275,56 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * char *arg = *argp; // find end of name - int key = 0; - int len; OptIndex opt_idx; - if (parse_option_name(arg, &key, &len, &opt_idx) == FAIL) { - *errmsg = e_invarg; + const char *const option_end = find_option_end(arg, &opt_idx); + + if (opt_idx != kOptInvalid) { + assert(option_end >= arg); + } else if (is_tty_option(arg)) { // Silently ignore TTY options. + return; + } else { // Invalid option name, skip. + *errmsg = e_unknown_option; return; } - // remember character after option name - int afterchar = (uint8_t)arg[len]; + // Remember character after option name. + uint8_t afterchar = (uint8_t)(*option_end); + char *p = (char *)option_end; - // skip white space, allow ":set ai ?" - while (ascii_iswhite(arg[len])) { - len++; + // Skip white space, allow ":set ai ?". + while (ascii_iswhite(*p)) { + p++; } - set_op_T op = get_op(arg + len); + set_op_T op = get_op(p); if (op != OP_NONE) { - len++; - } - - uint8_t nextchar = (uint8_t)arg[len]; // next non-white char after option name - - if (opt_idx == kOptInvalid && key == 0) { // found a mismatch: skip - *errmsg = e_unknown_option; - return; + p++; } - uint32_t flags; // flags for current option + uint8_t nextchar = (uint8_t)(*p); // next non-white char after option name + uint32_t flags = 0; // flags for current option void *varp = NULL; // pointer to variable for current option - if (opt_idx != kOptInvalid) { - if (options[opt_idx].var == NULL) { // hidden option: skip - // Only give an error message when requesting the value of - // a hidden option, ignore setting it. - if (vim_strchr("=:!&<", nextchar) == NULL - && (!(options[opt_idx].flags & P_BOOL) - || nextchar == '?')) { - *errmsg = e_unsupportedoption; - } - return; + if (options[opt_idx].var == NULL) { // hidden option: skip + // Only give an error message when requesting the value of + // a hidden option, ignore setting it. + if (vim_strchr("=:!&<", nextchar) == NULL + && (!option_has_type(opt_idx, kOptValTypeBoolean) || nextchar == '?')) { + *errmsg = e_unsupportedoption; } - - flags = options[opt_idx].flags; - varp = get_varp_scope(&(options[opt_idx]), opt_flags); - } else { - flags = P_STRING; + return; } + flags = options[opt_idx].flags; + varp = get_varp_scope(&(options[opt_idx]), opt_flags); + if (validate_opt_idx(curwin, opt_idx, opt_flags, flags, prefix, errmsg) == FAIL) { return; } if (vim_strchr("?=:!&<", nextchar) != NULL) { - *argp += len; + *argp = p; + if (nextchar == '&' && (*argp)[1] == 'v' && (*argp)[2] == 'i') { if ((*argp)[3] == 'm') { // "opt&vim": set to Vim default *argp += 3; @@ -1331,14 +1339,10 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * } } - // - // allow '=' and ':' as MS-DOS 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. if (nextchar == '?' - || (prefix == PREFIX_NONE - && vim_strchr("=:&<", nextchar) == NULL - && !(flags & P_BOOL))) { + || (prefix == PREFIX_NONE && vim_strchr("=:&<", nextchar) == NULL + && !option_has_type(opt_idx, kOptValTypeBoolean))) { // print value if (*did_show) { msg_putchar('\n'); // cursor below last one @@ -1346,29 +1350,26 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * gotocmdline(true); // cursor at status line *did_show = true; // remember that we did a line } - if (opt_idx != kOptInvalid) { - showoneopt(&options[opt_idx], opt_flags); - if (p_verbose > 0) { - // Mention where the option was last set. - if (varp == options[opt_idx].var) { - option_last_set_msg(options[opt_idx].last_set); - } else if ((int)options[opt_idx].indir & PV_WIN) { - option_last_set_msg(curwin->w_p_script_ctx[(int)options[opt_idx].indir & PV_MASK]); - } else if ((int)options[opt_idx].indir & PV_BUF) { - option_last_set_msg(curbuf->b_p_script_ctx[(int)options[opt_idx].indir & PV_MASK]); - } + showoneopt(&options[opt_idx], opt_flags); + + if (p_verbose > 0) { + // Mention where the option was last set. + if (varp == options[opt_idx].var) { + option_last_set_msg(options[opt_idx].last_set); + } else if ((int)options[opt_idx].indir & PV_WIN) { + option_last_set_msg(curwin->w_p_script_ctx[(int)options[opt_idx].indir & PV_MASK]); + } else if ((int)options[opt_idx].indir & PV_BUF) { + option_last_set_msg(curbuf->b_p_script_ctx[(int)options[opt_idx].indir & PV_MASK]); } - } else { - *errmsg = e_key_code_not_set; - return; } + if (nextchar != '?' && nextchar != NUL && !ascii_iswhite(afterchar)) { *errmsg = e_trailing; } return; } - if (flags & P_BOOL) { + if (option_has_type(opt_idx, kOptValTypeBoolean)) { if (vim_strchr("=:", nextchar) != NULL) { *errmsg = e_invarg; return; @@ -1690,7 +1691,7 @@ static void didset_options2(void) void check_options(void) { for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { - if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL) { + if ((option_has_type(opt_idx, kOptValTypeString)) && options[opt_idx].var != NULL) { check_string_option((char **)get_varp(&(options[opt_idx]))); } } @@ -1870,10 +1871,10 @@ static void apply_optionset_autocmd(OptIndex opt_idx, int opt_flags, OptVal oldv } char buf_type[7]; - typval_T oldval_tv = optval_as_tv(oldval); - typval_T oldval_g_tv = optval_as_tv(oldval_g); - typval_T oldval_l_tv = optval_as_tv(oldval_l); - typval_T newval_tv = optval_as_tv(newval); + typval_T oldval_tv = optval_as_tv(oldval, false); + typval_T oldval_g_tv = optval_as_tv(oldval_g, false); + typval_T oldval_l_tv = optval_as_tv(oldval_l, false); + typval_T newval_tv = optval_as_tv(newval, false); vim_snprintf(buf_type, sizeof(buf_type), "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); set_vim_var_tv(VV_OPTION_NEW, &newval_tv); @@ -3092,10 +3093,11 @@ OptIndex findoption_len(const char *const arg, const size_t len) bool is_tty_option(const char *name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - return (name[0] == 't' && name[1] == '_') || strequal(name, "term") || strequal(name, "ttytype"); + return find_tty_option_end(name) != NULL; } #define TCO_BUFFER_SIZE 8 + /// Get value of TTY option. /// /// @param name Name of TTY option. @@ -3145,7 +3147,7 @@ bool set_tty_option(const char *name, char *value) return false; } -/// Find index for an option +/// Find index for an option. /// /// @param[in] arg Option name. /// @@ -3203,27 +3205,7 @@ bool optval_equal(OptVal o1, OptVal o2) return o1.data.number == o2.data.number; case kOptValTypeString: return o1.data.string.size == o2.data.string.size - && strequal(o1.data.string.data, o2.data.string.data); - } - UNREACHABLE; -} - -/// Match type of OptVal with the type of the target option. Returns true if the types match and -/// false otherwise. -static bool optval_match_type(OptVal o, OptIndex opt_idx) -{ - assert(opt_idx != kOptInvalid); - uint32_t flags = options[opt_idx].flags; - - switch (o.type) { - case kOptValTypeNil: - return false; - case kOptValTypeBoolean: - return flags & P_BOOL; - case kOptValTypeNumber: - return flags & P_NUM; - case kOptValTypeString: - return flags & P_STRING; + && strnequal(o1.data.string.data, o2.data.string.data, o1.data.string.size); } UNREACHABLE; } @@ -3232,6 +3214,8 @@ static bool optval_match_type(OptVal o, OptIndex opt_idx) /// /// @param opt_idx Option index in options[] table. /// @param[out] varp Pointer to option variable. +/// +/// @return Option value stored in varp. OptVal optval_from_varp(OptIndex opt_idx, void *varp) { // Special case: 'modified' is b_changed, but we also want to consider it set when 'ff' or 'fenc' @@ -3240,19 +3224,17 @@ OptVal optval_from_varp(OptIndex opt_idx, void *varp) return BOOLEAN_OPTVAL(curbufIsChanged()); } - uint32_t flags = options[opt_idx].flags; - - OptValType type = kOptValTypeNil; - if (flags & P_BOOL) { - type = kOptValTypeBoolean; - } else if (flags & P_NUM) { - type = kOptValTypeNumber; - } else if (flags & P_STRING) { - type = kOptValTypeString; - } else { - abort(); + if (option_is_multitype(opt_idx)) { + // Multitype options are stored as OptVal. + return varp == NULL ? NIL_OPTVAL : *(OptVal *)varp; } + // If the option only supports a single type, it means that the index of the option's type flag + // corresponds to the value of the type enum. So get the index of the type flag using xctz() and + // use that as the option's type. + OptValType type = xctz(options[opt_idx].type_flags); + assert(type > kOptValTypeNil && type < kOptValTypeSize); + switch (type) { case kOptValTypeNil: return NIL_OPTVAL; @@ -3266,7 +3248,7 @@ OptVal optval_from_varp(OptIndex opt_idx, void *varp) UNREACHABLE; } -/// Set option var pointer value from Optval. +/// Set option var pointer value from OptVal. /// /// @param opt_idx Option index in options[] table. /// @param[out] varp Pointer to option variable. @@ -3275,7 +3257,7 @@ OptVal optval_from_varp(OptIndex opt_idx, void *varp) static void set_option_varp(OptIndex opt_idx, void *varp, OptVal value, bool free_oldval) FUNC_ATTR_NONNULL_ARG(2) { - assert(optval_match_type(value, opt_idx)); + assert(option_has_type(opt_idx, value.type)); if (free_oldval) { optval_free(optval_from_varp(opt_idx, varp)); @@ -3283,7 +3265,7 @@ static void set_option_varp(OptIndex opt_idx, void *varp, OptVal value, bool fre switch (value.type) { case kOptValTypeNil: - return; + abort(); case kOptValTypeBoolean: *(int *)varp = value.data.boolean; return; @@ -3374,7 +3356,7 @@ static OptVal optval_unset_local(OptIndex opt_idx, void *varp) // For global-local options, use the unset value of the local value. if (opt->indir & PV_BOTH) { // String global-local options always use an empty string for the unset value. - if (opt->flags & P_STRING) { + if (option_has_type(opt_idx, kOptValTypeString)) { return STATIC_CSTR_TO_OPTVAL(""); } @@ -3399,34 +3381,20 @@ static OptVal optval_unset_local(OptIndex opt_idx, void *varp) /// number, boolean or string, the function returns "Number/Boolean/String" static char *option_get_valid_types(OptIndex opt_idx) { - uint32_t flags = options[opt_idx].flags; - uint32_t type_count = 0; - StringBuilder str = KV_INITIAL_VALUE; kv_resize(str, 32); -#define OPTION_ADD_TYPE(typename) \ - do { \ - if (type_count == 0) { \ - kv_concat(str, typename); \ - } else { \ - kv_printf(str, "/%s", typename); \ - } \ - type_count++; \ - } while (0); - - if (flags & P_NUM) { - OPTION_ADD_TYPE("Number"); - } - if (flags & P_BOOL) { - OPTION_ADD_TYPE("Boolean"); - } - if (flags & P_STRING) { - OPTION_ADD_TYPE("String"); - } + // Iterate through every valid option value type and check if the option supports that type + for (OptValType type = 0; type < kOptValTypeSize; type++) { + if (option_has_type(opt_idx, type)) { + const char *typename = optval_type_get_name(type); - if (type_count == 0) { - abort(); + if (str.size == 0) { + kv_concat(str, typename); + } else { + kv_printf(str, "/%s", typename); + } + } } // Ensure that the string is NUL-terminated. @@ -3680,13 +3648,6 @@ static const char *set_option(const OptIndex opt_idx, void *varp, OptVal value, vimoption_T *opt = &options[opt_idx]; - static const char *optval_type_names[] = { - [kOptValTypeNil] = "Nil", - [kOptValTypeBoolean] = "Boolean", - [kOptValTypeNumber] = "Number", - [kOptValTypeString] = "String" - }; - if (value.type == kOptValTypeNil) { // Don't try to unset local value if scope is global. // TODO(famiu): Change this to forbid changing all non-local scopes when the API scope bug is @@ -3697,11 +3658,11 @@ static const char *set_option(const OptIndex opt_idx, void *varp, OptVal value, optval_free(value); value = optval_unset_local(opt_idx, varp); } - } else if (!optval_match_type(value, opt_idx)) { + } else if (!option_has_type(opt_idx, value.type)) { char *rep = optval_to_cstr(value); char *valid_types = option_get_valid_types(opt_idx); snprintf(errbuf, IOSIZE, _("Invalid value for option '%s': expected %s, got %s %s"), - opt->fullname, valid_types, optval_type_names[value.type], rep); + opt->fullname, valid_types, optval_type_get_name(value.type), rep); xfree(rep); xfree(valid_types); errmsg = errbuf; @@ -3943,11 +3904,11 @@ static void showoptions(bool all, int opt_flags) } else { varp = get_varp(opt); } - if (varp != NULL && (all || !optval_default(opt, varp))) { + if (varp != NULL && (all || !optval_default(opt_idx, varp))) { int len; if (opt_flags & OPT_ONECOLUMN) { len = Columns; - } else if (opt->flags & P_BOOL) { + } else if (option_has_type(opt_idx, kOptValTypeBoolean)) { len = 1; // a toggle option fits always } else { option_value2string(opt, opt_flags); @@ -3994,19 +3955,19 @@ static void showoptions(bool all, int opt_flags) } /// Return true if option "p" has its default value. -static int optval_default(vimoption_T *p, const void *varp) +static int optval_default(OptIndex opt_idx, void *varp) { - if (varp == NULL) { - return true; // hidden option is always at default - } - if (p->flags & P_NUM) { - return *(OptInt *)varp == (OptInt)(intptr_t)p->def_val; - } - if (p->flags & P_BOOL) { - return *(int *)varp == (int)(intptr_t)p->def_val; + vimoption_T *opt = &options[opt_idx]; + + // Hidden or immutable options always use their default value. + if (varp == NULL || opt->immutable) { + return true; } - // P_STRING - return strcmp(*(char **)varp, p->def_val) == 0; + + OptVal current_val = optval_from_varp(opt_idx, varp); + OptVal default_val = optval_from_varp(opt_idx, &opt->def_val); + + return optval_equal(current_val, default_val); } /// Send update to UIs with values of UI relevant options @@ -4018,16 +3979,7 @@ void ui_refresh_options(void) continue; } String name = cstr_as_string(options[opt_idx].fullname); - void *varp = options[opt_idx].var; - Object value = OBJECT_INIT; - if (flags & P_BOOL) { - value = BOOLEAN_OBJ(*(int *)varp); - } else if (flags & P_NUM) { - value = INTEGER_OBJ(*(OptInt *)varp); - } else if (flags & P_STRING) { - // cstr_as_string handles NULL string - value = CSTR_AS_OBJ(*(char **)varp); - } + Object value = optval_as_object(optval_from_varp(opt_idx, options[opt_idx].var)); ui_call_option_set(name, value); } if (p_mouse != NULL) { @@ -4039,29 +3991,30 @@ void ui_refresh_options(void) /// must not be called with a hidden option! /// /// @param opt_flags OPT_LOCAL or OPT_GLOBAL -static void showoneopt(vimoption_T *p, int opt_flags) +static void showoneopt(vimoption_T *opt, int opt_flags) { int save_silent = silent_mode; silent_mode = false; info_message = true; // use os_msg(), not os_errmsg() - void *varp = get_varp_scope(p, opt_flags); + OptIndex opt_idx = get_opt_idx(opt); + void *varp = get_varp_scope(opt, opt_flags); // for 'modified' we also need to check if 'ff' or 'fenc' changed. - if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed - ? !curbufIsChanged() : !*(int *)varp)) { + if (option_has_type(opt_idx, kOptValTypeBoolean) + && ((int *)varp == &curbuf->b_changed ? !curbufIsChanged() : !*(int *)varp)) { msg_puts("no"); - } else if ((p->flags & P_BOOL) && *(int *)varp < 0) { + } else if (option_has_type(opt_idx, kOptValTypeBoolean) && *(int *)varp < 0) { msg_puts("--"); } else { msg_puts(" "); } - msg_puts(p->fullname); - if (!(p->flags & P_BOOL)) { + msg_puts(opt->fullname); + if (!(option_has_type(opt_idx, kOptValTypeBoolean))) { msg_putchar('='); // put value string in NameBuff - option_value2string(p, opt_flags); + option_value2string(opt, opt_flags); msg_outtrans(NameBuff, 0); } @@ -4122,7 +4075,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) continue; } // Global values are only written when not at the default value. - if ((opt_flags & OPT_GLOBAL) && optval_default(opt, varp)) { + if ((opt_flags & OPT_GLOBAL) && optval_default(opt_idx, varp)) { continue; } @@ -4143,7 +4096,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) // default, need to write it too. if (!(opt_flags & OPT_GLOBAL) && !local_only) { void *varp_fresh = get_varp_scope(opt, OPT_GLOBAL); // local value - if (!optval_default(opt, varp_fresh)) { + if (!optval_default(opt_idx, varp_fresh)) { round = 1; varp_local = varp; varp = varp_fresh; @@ -4162,15 +4115,15 @@ int makeset(FILE *fd, int opt_flags, int local_only) cmd = "setlocal"; } - if (opt->flags & P_BOOL) { + if (option_has_type(opt_idx, kOptValTypeBoolean)) { if (put_setbool(fd, cmd, opt->fullname, *(int *)varp) == FAIL) { return FAIL; } - } else if (opt->flags & P_NUM) { + } else if (option_has_type(opt_idx, kOptValTypeNumber)) { if (put_setnum(fd, cmd, opt->fullname, (OptInt *)varp) == FAIL) { return FAIL; } - } else { // P_STRING + } else { // string int do_endif = false; // Don't set 'syntax' and 'filetype' again if the value is @@ -4688,6 +4641,13 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win) return &(buf->b_p_wm); } +/// Get option index from option pointer +static inline OptIndex get_opt_idx(vimoption_T *opt) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE +{ + return (OptIndex)(opt - options); +} + /// Get pointer to option variable. static inline void *get_varp(vimoption_T *p) { @@ -5179,7 +5139,7 @@ void set_imsearch_global(buf_T *buf) p_imsearch = buf->b_p_imsearch; } -static int expand_option_idx = kOptInvalid; +static OptIndex expand_option_idx = kOptInvalid; static int expand_option_start_col = 0; static char expand_option_name[5] = { 't', '_', NUL, NUL, NUL }; static int expand_option_flags = 0; @@ -5275,7 +5235,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) return; } flags = options[opt_idx].flags; - if (flags & P_BOOL) { + if (option_has_type(opt_idx, kOptValTypeBoolean)) { xp->xp_context = EXPAND_NOTHING; return; } @@ -5336,7 +5296,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) xp->xp_context = EXPAND_NOTHING; } - if (is_term_option || (flags & P_NUM)) { + if (is_term_option || option_has_type(opt_idx, kOptValTypeNumber)) { return; } @@ -5494,7 +5454,7 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char *fuzzystr, int *numM continue; } if (xp->xp_context == EXPAND_BOOL_SETTINGS - && !(options[opt_idx].flags & P_BOOL)) { + && !(option_has_type(opt_idx, kOptValTypeBoolean))) { continue; } @@ -5638,7 +5598,7 @@ int ExpandSettingSubtract(expand_T *xp, regmatch_T *regmatch, int *numMatches, c uint32_t option_flags = options[expand_option_idx].flags; - if (option_flags & P_NUM) { + if (option_has_type(expand_option_idx, kOptValTypeNumber)) { return ExpandOldSetting(numMatches, matches); } else if (option_flags & P_COMMA) { // Split the option by comma, then present each option to the user if @@ -5733,11 +5693,13 @@ int ExpandSettingSubtract(expand_T *xp, regmatch_T *regmatch, int *numMatches, c /// NameBuff[]. Must not be called with a hidden option! /// /// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL -static void option_value2string(vimoption_T *opp, int scope) +/// +/// TODO(famiu): Replace this with optval_to_cstr() if possible. +static void option_value2string(vimoption_T *opt, int scope) { - void *varp = get_varp_scope(opp, scope); + void *varp = get_varp_scope(opt, scope); - if (opp->flags & P_NUM) { + if (option_has_type(get_opt_idx(opt), kOptValTypeNumber)) { OptInt wc = 0; if (wc_use_keyname(varp, &wc)) { @@ -5750,11 +5712,11 @@ static void option_value2string(vimoption_T *opp, int scope) "%" PRId64, (int64_t)(*(OptInt *)varp)); } - } else { // P_STRING + } else { // string varp = *(char **)(varp); if (varp == NULL) { // Just in case. NameBuff[0] = NUL; - } else if (opp->flags & P_EXPAND) { + } else if (opt->flags & P_EXPAND) { home_replace(NULL, varp, NameBuff, MAXPATHL, false); } else { xstrlcpy(NameBuff, varp, MAXPATHL); @@ -6155,15 +6117,8 @@ dict_T *get_winbuf_options(const int bufopt) void *varp = get_varp(opt); if (varp != NULL) { - if (opt->flags & P_STRING) { - tv_dict_add_str(d, opt->fullname, strlen(opt->fullname), - *(const char **)varp); - } else if (opt->flags & P_NUM) { - tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), - *(OptInt *)varp); - } else { - tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), *(int *)varp); - } + typval_T opt_tv = optval_as_tv(optval_from_varp(opt_idx, varp), true); + tv_dict_add_tv(d, opt->fullname, strlen(opt->fullname), &opt_tv); } } } @@ -6254,24 +6209,11 @@ static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, wi PUT(dict, "last_set_linenr", INTEGER_OBJ(last_set.script_ctx.sc_lnum)); PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)last_set.channel_id)); - const char *type; - Object def; // TODO(bfredl): do you even nocp? - char *def_val = opt->def_val; - if (opt->flags & P_STRING) { - type = "string"; - def = CSTR_TO_OBJ(def_val ? def_val : ""); - } else if (opt->flags & P_NUM) { - type = "number"; - def = INTEGER_OBJ((Integer)(intptr_t)def_val); - } else if (opt->flags & P_BOOL) { - type = "boolean"; - def = BOOLEAN_OBJ((intptr_t)def_val); - } else { - type = ""; def = NIL; - } - PUT(dict, "type", CSTR_TO_OBJ(type)); - PUT(dict, "default", def); + OptVal def = optval_from_varp(get_opt_idx(opt), &opt->def_val); + + PUT(dict, "type", CSTR_TO_OBJ(optval_type_get_name(def.type))); + PUT(dict, "default", optval_as_object(optval_copy(def))); PUT(dict, "allows_duplicates", BOOLEAN_OBJ(!(opt->flags & P_NODUP))); return dict; diff --git a/src/nvim/option.h b/src/nvim/option.h index db438342ab..034c3de148 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -8,6 +8,7 @@ #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep +#include "nvim/math.h" #include "nvim/option_defs.h" // IWYU pragma: export #include "nvim/types_defs.h" // IWYU pragma: keep @@ -38,17 +39,16 @@ typedef enum { #define VAR_WIN ((char *)-1) typedef struct vimoption { - char *fullname; ///< full option name - char *shortname; ///< permissible abbreviation - uint32_t flags; ///< see above - void *var; ///< global option: pointer to variable; - ///< window-local option: VAR_WIN; - ///< buffer-local option: global value - idopt_T indir; ///< global option: PV_NONE; - ///< local option: indirect option index - ///< callback function to invoke after an option is modified to validate and - ///< apply the new value. - bool immutable; ///< option value cannot be changed from the default value. + char *fullname; ///< full option name + char *shortname; ///< permissible abbreviation + uint32_t flags; ///< see above + OptTypeFlags type_flags; ///< option type flags, see OptValType + void *var; ///< global option: pointer to variable; + ///< window-local option: VAR_WIN; + ///< buffer-local option: global value + idopt_T indir; ///< global option: PV_NONE; + ///< local option: indirect option index + bool immutable; ///< option value cannot be changed from the default value. /// callback function to invoke after an option is modified to validate and /// apply the new value. @@ -85,7 +85,7 @@ typedef enum { OPT_ONECOLUMN = 0x40, ///< list options one per line OPT_NO_REDRAW = 0x80, ///< ignore redraw flags on option OPT_SKIPRTP = 0x100, ///< "skiprtp" in 'sessionoptions' -} OptionFlags; +} OptionSetFlags; /// Return value from get_option_attrs(). enum { @@ -94,6 +94,22 @@ enum { SOPT_BUF = 0x04, ///< Option has buffer-local value }; +/// Get name of OptValType as a string. +static inline const char *optval_type_get_name(const OptValType type) +{ + switch (type) { + case kOptValTypeNil: + return "nil"; + case kOptValTypeBoolean: + return "boolean"; + case kOptValTypeNumber: + return "number"; + case kOptValTypeString: + return "string"; + } + UNREACHABLE; +} + // OptVal helper macros. #define NIL_OPTVAL ((OptVal) { .type = kOptValTypeNil }) #define BOOLEAN_OPTVAL(b) ((OptVal) { .type = kOptValTypeBoolean, .data.boolean = b }) @@ -108,3 +124,24 @@ enum { #ifdef INCLUDE_GENERATED_DECLARATIONS # include "option.h.generated.h" #endif + +/// Check if option supports a specific type. +static inline bool option_has_type(OptIndex opt_idx, OptValType type) +{ + // Ensure that type flags variable can hold all types. + STATIC_ASSERT(kOptValTypeSize <= sizeof(OptTypeFlags) * 8, + "Option type_flags cannot fit all option types"); + // Ensure that the type is valid before accessing type_flags. + assert(type > kOptValTypeNil && type < kOptValTypeSize); + // Bitshift 1 by the value of type to get the type's corresponding flag, and check if it's set in + // the type_flags bit_field. + return get_option(opt_idx)->type_flags & (1 << type); +} + +/// Check if option is multitype (supports multiple types). +static inline bool option_is_multitype(OptIndex opt_idx) +{ + const OptTypeFlags type_flags = get_option(opt_idx)->type_flags; + assert(type_flags != 0); + return !is_power_of_two(type_flags); +} diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 28718c6269..7ccf09b934 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -8,14 +8,21 @@ #include "nvim/regexp_defs.h" #include "nvim/types_defs.h" -/// Option value type +/// Option value type. +/// These types are also used as type flags by using the type value as an index for the type_flags +/// bit field (@see option_has_type()). typedef enum { - kOptValTypeNil = 0, + kOptValTypeNil = -1, // Make sure Nil can't be bitshifted and used as an option type flag. kOptValTypeBoolean, kOptValTypeNumber, kOptValTypeString, } OptValType; +/// Always update this whenever a new option type is added. +#define kOptValTypeSize (kOptValTypeString + 1) + +typedef uint32_t OptTypeFlags; + typedef union { // boolean options are actually tri-states because they have a third "None" value. TriState boolean; diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index 66185940ca..cbdec2e0db 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -6,55 +6,49 @@ // option_vars.h: definition of global variables for settable options // Option Flags -#define P_BOOL 0x01U ///< the option is boolean -#define P_NUM 0x02U ///< the option is numeric -#define P_STRING 0x04U ///< the option is a string -#define P_ALLOCED 0x08U ///< the string option is in allocated memory, +#define P_ALLOCED 0x01U ///< the option is in allocated memory, ///< must use free_string_option() when ///< assigning new value. Not set if default is ///< the same. -#define P_EXPAND 0x10U ///< environment expansion. NOTE: P_EXPAND can +#define P_EXPAND 0x02U ///< environment expansion. NOTE: P_EXPAND can ///< never be used for local or hidden options -#define P_NO_DEF_EXP 0x20U ///< do not expand default value -#define P_NODEFAULT 0x40U ///< don't set to default value -#define P_DEF_ALLOCED 0x80U ///< default value is in allocated memory, must +#define P_NO_DEF_EXP 0x04U ///< do not expand default value +#define P_NODEFAULT 0x08U ///< don't set to default value +#define P_DEF_ALLOCED 0x10U ///< default value is in allocated memory, must ///< 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_WAS_SET 0x20U ///< option has been set/reset +#define P_NO_MKRC 0x40U ///< don't include in :mkvimrc output // when option changed, what to display: -#define P_UI_OPTION 0x400U ///< send option to remote UI -#define P_RTABL 0x800U ///< redraw tabline -#define P_RSTAT 0x1000U ///< redraw status lines -#define P_RWIN 0x2000U ///< redraw current window and recompute text -#define P_RBUF 0x4000U ///< redraw current buffer and recompute text -#define P_RALL 0x6000U ///< redraw all windows -#define P_RCLR 0x7000U ///< clear and redraw all - -#define P_COMMA 0x8000U ///< comma separated list -#define P_ONECOMMA 0x18000U ///< P_COMMA and cannot have two consecutive +#define P_UI_OPTION 0x80U ///< send option to remote UI +#define P_RTABL 0x100U ///< redraw tabline +#define P_RSTAT 0x200U ///< redraw status lines +#define P_RWIN 0x400U ///< redraw current window and recompute text +#define P_RBUF 0x800U ///< redraw current buffer and recompute text +#define P_RALL 0xC00U ///< redraw all windows +#define P_RCLR 0xE00U ///< clear and redraw all + +#define P_COMMA 0x1000U ///< comma separated list +#define P_ONECOMMA 0x3000U ///< P_COMMA and cannot have two consecutive ///< commas -#define P_NODUP 0x20000U ///< don't allow duplicate strings -#define P_FLAGLIST 0x40000U ///< list of single-char flags - -#define P_SECURE 0x80000U ///< cannot change in modeline or secure mode -#define P_GETTEXT 0x100000U ///< expand default value with _() -#define P_NOGLOB 0x200000U ///< do not use local value for global vimrc -#define P_NFNAME 0x400000U ///< only normal file name chars allowed -#define P_INSECURE 0x800000U ///< option was set from a modeline -#define P_PRI_MKRC 0x1000000U ///< priority for :mkvimrc (setting option +#define P_NODUP 0x4000U ///< don't allow duplicate strings +#define P_FLAGLIST 0x8000U ///< list of single-char flags + +#define P_SECURE 0x10000U ///< cannot change in modeline or secure mode +#define P_GETTEXT 0x20000U ///< expand default value with _() +#define P_NOGLOB 0x40000U ///< do not use local value for global vimrc +#define P_NFNAME 0x80000U ///< only normal file name chars allowed +#define P_INSECURE 0x100000U ///< option was set from a modeline +#define P_PRI_MKRC 0x200000U ///< priority for :mkvimrc (setting option ///< has side effects) -#define P_NO_ML 0x2000000U ///< not allowed in modeline -#define P_CURSWANT 0x4000000U ///< update curswant required; not needed +#define P_NO_ML 0x400000U ///< not allowed in modeline +#define P_CURSWANT 0x800000U ///< update curswant required; not needed ///< when there is a redraw flag -#define P_NDNAME 0x8000000U ///< only normal dir name chars allowed -#define P_RWINONLY 0x10000000U ///< only redraw current window -#define P_MLE 0x20000000U ///< under control of 'modelineexpr' -#define P_FUNC 0x40000000U ///< accept a function reference or a lambda -#define P_COLON 0x80000000U ///< values use colons to create sublists -// Warning: Currently we have used all 32 bits for option flags, and adding more -// flags will overflow it. Adding another flag will need to change how -// it's stored first. +#define P_NDNAME 0x1000000U ///< only normal dir name chars allowed +#define P_RWINONLY 0x2000000U ///< only redraw current window +#define P_MLE 0x4000000U ///< under control of 'modelineexpr' +#define P_FUNC 0x8000000U ///< accept a function reference or a lambda +#define P_COLON 0x10000000U ///< values use colons to create sublists #define HIGHLIGHT_INIT \ "8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \ diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 8f0be0eb1b..edd7423e69 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -5,7 +5,7 @@ --- @field short_desc? string|fun(): string --- @field varname? string --- @field pv_name? string ---- @field type 'bool'|'number'|'string' +--- @field type 'boolean'|'number'|'string' --- @field immutable? boolean --- @field list? 'comma'|'onecomma'|'commacolon'|'onecommacolon'|'flags'|'flagscomma' --- @field scope vim.option_scope[] @@ -105,7 +105,7 @@ return { full_name = 'allowrevins', scope = { 'global' }, short_desc = N_('allow CTRL-_ in Insert and Command-line mode'), - type = 'bool', + type = 'boolean', varname = 'p_ari', }, { @@ -176,7 +176,7 @@ return { redraw = { 'curswant' }, scope = { 'window' }, short_desc = N_('Arabic as a default second language'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'arshape', @@ -199,7 +199,7 @@ return { redraw = { 'all_windows', 'ui_option' }, scope = { 'global' }, short_desc = N_('do shaping for Arabic characters'), - type = 'bool', + type = 'boolean', varname = 'p_arshape', }, { @@ -217,7 +217,7 @@ return { full_name = 'autochdir', scope = { 'global' }, short_desc = N_('change directory to the file in the current window'), - type = 'bool', + type = 'boolean', varname = 'p_acd', }, { @@ -239,7 +239,7 @@ return { full_name = 'autoindent', scope = { 'buffer' }, short_desc = N_('take indent for new line from previous line'), - type = 'bool', + type = 'boolean', varname = 'p_ai', }, { @@ -259,7 +259,7 @@ return { full_name = 'autoread', scope = { 'global', 'buffer' }, short_desc = N_('autom. read file when changed outside of Vim'), - type = 'bool', + type = 'boolean', varname = 'p_ar', }, { @@ -284,7 +284,7 @@ return { full_name = 'autowrite', scope = { 'global' }, short_desc = N_('automatically write file if changed'), - type = 'bool', + type = 'boolean', varname = 'p_aw', }, { @@ -299,7 +299,7 @@ return { full_name = 'autowriteall', scope = { 'global' }, short_desc = N_("as 'autowrite', but works with more commands"), - type = 'bool', + type = 'boolean', varname = 'p_awa', }, { @@ -387,7 +387,7 @@ return { full_name = 'backup', scope = { 'global' }, short_desc = N_('keep backup file after overwriting a file'), - type = 'bool', + type = 'boolean', varname = 'p_bk', }, { @@ -671,7 +671,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('read/write/edit file in binary mode'), - type = 'bool', + type = 'boolean', varname = 'p_bin', }, { @@ -699,7 +699,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('a Byte Order Mark to the file'), - type = 'bool', + type = 'boolean', varname = 'p_bomb', }, { @@ -733,7 +733,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('wrapped line repeats indent'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'briopt', @@ -848,7 +848,7 @@ return { scope = { 'buffer' }, short_desc = N_('whether the buffer shows up in the buffer list'), tags = { 'E85' }, - type = 'bool', + type = 'boolean', varname = 'p_bl', }, { @@ -950,7 +950,7 @@ return { scope = { 'global' }, secure = true, short_desc = N_(':cd without argument goes to the home directory'), - type = 'bool', + type = 'boolean', varname = 'p_cdh', }, { @@ -1088,7 +1088,7 @@ return { full_name = 'cindent', scope = { 'buffer' }, short_desc = N_('do C program indenting'), - type = 'bool', + type = 'boolean', varname = 'p_cin', }, { @@ -1341,7 +1341,7 @@ return { full_name = 'compatible', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -1558,7 +1558,7 @@ return { full_name = 'confirm', scope = { 'global' }, short_desc = N_('ask what to do about unsaved/read-only files'), - type = 'bool', + type = 'boolean', varname = 'p_confirm', }, { @@ -1578,7 +1578,7 @@ return { full_name = 'copyindent', scope = { 'buffer' }, short_desc = N_("make 'autoindent' use existing indent structure"), - type = 'bool', + type = 'boolean', varname = 'p_ci', }, { @@ -1843,7 +1843,7 @@ return { pv_name = 'p_crbind', scope = { 'window' }, short_desc = N_('move cursor in window as it moves in other windows'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'cuc', @@ -1862,7 +1862,7 @@ return { redraw = { 'current_window_only' }, scope = { 'window' }, short_desc = N_('highlight the screen column of the cursor'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'cul', @@ -1877,7 +1877,7 @@ return { redraw = { 'current_window_only' }, scope = { 'window' }, short_desc = N_('highlight the screen line of the cursor'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'culopt', @@ -1978,7 +1978,7 @@ return { full_name = 'delcombine', scope = { 'global' }, short_desc = N_('delete combining characters on their own'), - type = 'bool', + type = 'boolean', varname = 'p_deco', }, { @@ -2030,7 +2030,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('diff mode for the current window'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'dex', @@ -2183,7 +2183,7 @@ return { full_name = 'digraph', scope = { 'global' }, short_desc = N_('enable the entering of digraphs in Insert mode'), - type = 'bool', + type = 'boolean', varname = 'p_dg', }, { @@ -2299,7 +2299,7 @@ return { full_name = 'edcompatible', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -2317,7 +2317,7 @@ return { redraw = { 'all_windows', 'ui_option' }, scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', varname = 'p_emoji', }, { @@ -2354,7 +2354,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('write CTRL-Z for last line in file'), - type = 'bool', + type = 'boolean', varname = 'p_eof', }, { @@ -2380,7 +2380,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('write for last line in file'), - type = 'bool', + type = 'boolean', varname = 'p_eol', }, { @@ -2406,7 +2406,7 @@ return { full_name = 'equalalways', scope = { 'global' }, short_desc = N_('windows are automatically made the same size'), - type = 'bool', + type = 'boolean', varname = 'p_ea', }, { @@ -2442,7 +2442,7 @@ return { full_name = 'errorbells', scope = { 'global' }, short_desc = N_('ring the bell for error messages'), - type = 'bool', + type = 'boolean', varname = 'p_eb', }, { @@ -2517,7 +2517,7 @@ return { full_name = 'expandtab', scope = { 'buffer' }, short_desc = N_('use spaces when is inserted'), - type = 'bool', + type = 'boolean', varname = 'p_et', }, { @@ -2539,7 +2539,7 @@ return { scope = { 'global' }, secure = true, short_desc = N_('read .nvimrc and .exrc in the current directory'), - type = 'bool', + type = 'boolean', varname = 'p_exrc', }, { @@ -2769,7 +2769,7 @@ return { full_name = 'fileignorecase', scope = { 'global' }, short_desc = N_('ignore case when using file names'), - type = 'bool', + type = 'boolean', varname = 'p_fic', }, { @@ -2901,7 +2901,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('make sure last line in file has '), - type = 'bool', + type = 'boolean', varname = 'p_fixeol', }, { @@ -2960,7 +2960,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('set to display all folds open'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'fde', @@ -3329,7 +3329,7 @@ return { scope = { 'global' }, secure = true, short_desc = N_('whether to invoke fsync() after file write'), - type = 'bool', + type = 'boolean', varname = 'p_fs', }, { @@ -3353,7 +3353,7 @@ return { full_name = 'gdefault', scope = { 'global' }, short_desc = N_('the ":substitute" flag \'g\' is default on'), - type = 'bool', + type = 'boolean', varname = 'p_gd', }, { @@ -3849,7 +3849,7 @@ return { full_name = 'hidden', scope = { 'global' }, short_desc = N_("don't unload buffer when it is |abandon|ed"), - type = 'bool', + type = 'boolean', varname = 'p_hid', }, { @@ -3885,7 +3885,7 @@ return { full_name = 'hkmap', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -3894,7 +3894,7 @@ return { full_name = 'hkmapp', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -3926,7 +3926,7 @@ return { redraw = { 'all_windows' }, scope = { 'global' }, short_desc = N_('highlight matches with last search pattern'), - type = 'bool', + type = 'boolean', varname = 'p_hls', }, { @@ -3945,7 +3945,7 @@ return { full_name = 'icon', scope = { 'global' }, short_desc = N_('Vim set the text of the window icon'), - type = 'bool', + type = 'boolean', varname = 'p_icon', }, { @@ -3981,7 +3981,7 @@ return { full_name = 'ignorecase', scope = { 'global' }, short_desc = N_('ignore case in search patterns'), - type = 'bool', + type = 'boolean', varname = 'p_ic', }, { @@ -3998,7 +3998,7 @@ return { full_name = 'imcmdline', scope = { 'global' }, short_desc = N_('use IM when starting to edit a command line'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'imd', @@ -4016,7 +4016,7 @@ return { full_name = 'imdisable', scope = { 'global' }, short_desc = N_('do not use the IM in any mode'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'imi', @@ -4195,7 +4195,7 @@ return { full_name = 'incsearch', scope = { 'global' }, short_desc = N_('highlight match while typing search pattern'), - type = 'bool', + type = 'boolean', varname = 'p_is', }, { @@ -4283,7 +4283,7 @@ return { full_name = 'infercase', scope = { 'buffer' }, short_desc = N_('adjust case of match for keyword completion'), - type = 'bool', + type = 'boolean', varname = 'p_inf', }, { @@ -4292,7 +4292,7 @@ return { full_name = 'insertmode', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -4469,7 +4469,7 @@ return { full_name = 'joinspaces', scope = { 'global' }, short_desc = N_('two spaces after a period with a join command'), - type = 'bool', + type = 'boolean', varname = 'p_js', }, { @@ -4664,7 +4664,7 @@ return { full_name = 'langnoremap', scope = { 'global' }, short_desc = N_("do not apply 'langmap' to mapped characters"), - type = 'bool', + type = 'boolean', varname = 'p_lnr', }, { @@ -4679,7 +4679,7 @@ return { full_name = 'langremap', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', varname = 'p_lrm', }, { @@ -4718,7 +4718,7 @@ return { full_name = 'lazyredraw', scope = { 'global' }, short_desc = N_("don't redraw while executing macros"), - type = 'bool', + type = 'boolean', varname = 'p_lz', }, { @@ -4739,7 +4739,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('wrap long lines at a blank'), - type = 'bool', + type = 'boolean', }, { defaults = { @@ -4802,7 +4802,7 @@ return { full_name = 'lisp', scope = { 'buffer' }, short_desc = N_('indenting for Lisp'), - type = 'bool', + type = 'boolean', varname = 'p_lisp', }, { @@ -4868,7 +4868,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_(' and '), - type = 'bool', + type = 'boolean', }, { abbreviation = 'lcs', @@ -4996,7 +4996,7 @@ return { full_name = 'loadplugins', scope = { 'global' }, short_desc = N_('load plugin scripts when starting up'), - type = 'bool', + type = 'boolean', varname = 'p_lpl', }, { @@ -5013,7 +5013,7 @@ return { full_name = 'magic', scope = { 'global' }, short_desc = N_('special characters in search patterns'), - type = 'bool', + type = 'boolean', varname = 'p_magic', }, { @@ -5280,7 +5280,7 @@ return { full_name = 'modeline', scope = { 'buffer' }, short_desc = N_('recognize modelines at start or end of file'), - type = 'bool', + type = 'boolean', varname = 'p_ml', }, { @@ -5297,7 +5297,7 @@ return { scope = { 'global' }, secure = true, short_desc = N_('allow some options to be set in modeline'), - type = 'bool', + type = 'boolean', varname = 'p_mle', }, { @@ -5329,7 +5329,7 @@ return { scope = { 'buffer' }, short_desc = N_('changes to the text are not possible'), tags = { 'E21' }, - type = 'bool', + type = 'boolean', varname = 'p_ma', }, { @@ -5364,7 +5364,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('buffer has been modified'), - type = 'bool', + type = 'boolean', varname = 'p_mod', }, { @@ -5377,7 +5377,7 @@ return { full_name = 'more', scope = { 'global' }, short_desc = N_('listings when the whole screen is filled'), - type = 'bool', + type = 'boolean', varname = 'p_more', }, { @@ -5443,7 +5443,7 @@ return { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('keyboard focus follows the mouse'), - type = 'bool', + type = 'boolean', varname = 'p_mousef', }, { @@ -5459,7 +5459,7 @@ return { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('hide mouse pointer while typing'), - type = 'bool', + type = 'boolean', varname = 'p_mh', }, { @@ -5536,7 +5536,7 @@ return { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('deliver mouse move events to input queue'), - type = 'bool', + type = 'boolean', varname = 'p_mousemev', }, { @@ -5733,7 +5733,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('print the line number in front of each line'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'nuw', @@ -5797,7 +5797,7 @@ return { full_name = 'opendevice', scope = { 'global' }, short_desc = N_('allow reading/writing devices on MS-Windows'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'opfunc', @@ -5864,7 +5864,7 @@ return { pri_mkrc = true, scope = { 'global' }, short_desc = N_('pasting text'), - type = 'bool', + type = 'boolean', varname = 'p_paste', }, { @@ -6004,7 +6004,7 @@ return { full_name = 'preserveindent', scope = { 'buffer' }, short_desc = N_('preserve the indent structure when reindenting'), - type = 'bool', + type = 'boolean', varname = 'p_pi', }, { @@ -6035,14 +6035,14 @@ return { scope = { 'window' }, short_desc = N_('identifies the preview window'), tags = { 'E590' }, - type = 'bool', + type = 'boolean', }, { defaults = { if_true = true }, full_name = 'prompt', scope = { 'global' }, short_desc = N_('enable prompt in Ex mode'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -6176,7 +6176,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('disallow writing the buffer'), - type = 'bool', + type = 'boolean', varname = 'p_ro', }, { @@ -6292,14 +6292,14 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('show relative line number in front of each line'), - type = 'bool', + type = 'boolean', }, { defaults = { if_true = true }, full_name = 'remap', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -6328,7 +6328,7 @@ return { full_name = 'revins', scope = { 'global' }, short_desc = N_('inserting characters will work backwards'), - type = 'bool', + type = 'boolean', varname = 'p_ri', }, { @@ -6349,7 +6349,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('window is right-to-left oriented'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'rlc', @@ -6403,7 +6403,7 @@ return { redraw = { 'statuslines' }, scope = { 'global' }, short_desc = N_('show cursor line and column in the status line'), - type = 'bool', + type = 'boolean', varname = 'p_ru', }, { @@ -6598,7 +6598,7 @@ return { pv_name = 'p_scbind', scope = { 'window' }, short_desc = N_('scroll in window as other windows scroll'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'sj', @@ -6700,7 +6700,7 @@ return { scope = { 'global' }, secure = true, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', varname = 'p_secure', }, { @@ -7184,7 +7184,7 @@ return { full_name = 'shellslash', scope = { 'global' }, short_desc = N_('use forward slash for shell file names'), - type = 'bool', + type = 'boolean', varname = 'p_ssl', }, { @@ -7205,7 +7205,7 @@ return { full_name = 'shelltemp', scope = { 'global' }, short_desc = N_('whether to use a temp file for shell commands'), - type = 'bool', + type = 'boolean', varname = 'p_stmp', }, { @@ -7262,7 +7262,7 @@ return { full_name = 'shiftround', scope = { 'global' }, short_desc = N_('round indent to multiple of shiftwidth'), - type = 'bool', + type = 'boolean', varname = 'p_sr', }, { @@ -7394,7 +7394,7 @@ return { full_name = 'showcmd', scope = { 'global' }, short_desc = N_('show (partial) command in status line'), - type = 'bool', + type = 'boolean', varname = 'p_sc', }, { @@ -7437,7 +7437,7 @@ return { full_name = 'showfulltag', scope = { 'global' }, short_desc = N_('show full tag pattern when completing tag'), - type = 'bool', + type = 'boolean', varname = 'p_sft', }, { @@ -7463,7 +7463,7 @@ return { full_name = 'showmatch', scope = { 'global' }, short_desc = N_('briefly jump to matching bracket if insert one'), - type = 'bool', + type = 'boolean', varname = 'p_sm', }, { @@ -7477,7 +7477,7 @@ return { full_name = 'showmode', scope = { 'global' }, short_desc = N_('message on status line to show current mode'), - type = 'bool', + type = 'boolean', varname = 'p_smd', }, { @@ -7592,7 +7592,7 @@ return { full_name = 'smartcase', scope = { 'global' }, short_desc = N_('no ignore case when pattern has uppercase'), - type = 'bool', + type = 'boolean', varname = 'p_scs', }, { @@ -7622,7 +7622,7 @@ return { full_name = 'smartindent', scope = { 'buffer' }, short_desc = N_('smart autoindenting for C programs'), - type = 'bool', + type = 'boolean', varname = 'p_si', }, { @@ -7643,7 +7643,7 @@ return { full_name = 'smarttab', scope = { 'global' }, short_desc = N_("use 'shiftwidth' when inserting "), - type = 'bool', + type = 'boolean', varname = 'p_sta', }, { @@ -7665,7 +7665,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_("scroll by screen lines when 'wrap' is set"), - type = 'bool', + type = 'boolean', }, { abbreviation = 'sts', @@ -7704,7 +7704,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('spell checking'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'spc', @@ -7935,7 +7935,7 @@ return { full_name = 'splitbelow', scope = { 'global' }, short_desc = N_('new window from split is below the current one'), - type = 'bool', + type = 'boolean', varname = 'p_sb', }, { @@ -7973,7 +7973,7 @@ return { full_name = 'splitright', scope = { 'global' }, short_desc = N_('new window is put right of the current one'), - type = 'bool', + type = 'boolean', varname = 'p_spr', }, { @@ -7994,7 +7994,7 @@ return { full_name = 'startofline', scope = { 'global' }, short_desc = N_('commands move cursor to first non-blank in line'), - type = 'bool', + type = 'boolean', varname = 'p_sol', vim = false, }, @@ -8356,7 +8356,7 @@ return { redraw = { 'statuslines' }, scope = { 'buffer' }, short_desc = N_('whether to use a swapfile for a buffer'), - type = 'bool', + type = 'boolean', varname = 'p_swf', }, { @@ -8610,7 +8610,7 @@ return { full_name = 'tagbsearch', scope = { 'global' }, short_desc = N_('use binary searching in tags files'), - type = 'bool', + type = 'boolean', varname = 'p_tbs', }, { @@ -8677,7 +8677,7 @@ return { full_name = 'tagrelative', scope = { 'global' }, short_desc = N_('file names in tag file are relative'), - type = 'bool', + type = 'boolean', varname = 'p_tr', }, { @@ -8727,7 +8727,7 @@ return { full_name = 'tagstack', scope = { 'global' }, short_desc = N_('push tags onto the tag stack'), - type = 'bool', + type = 'boolean', varname = 'p_tgst', }, { @@ -8746,7 +8746,7 @@ return { full_name = 'termbidi', scope = { 'global' }, short_desc = N_('terminal takes care of bi-directionality'), - type = 'bool', + type = 'boolean', varname = 'p_tbidi', }, { @@ -8773,7 +8773,7 @@ return { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('Terminal true color support'), - type = 'bool', + type = 'boolean', varname = 'p_tgc', }, { @@ -8820,7 +8820,7 @@ return { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('synchronize redraw output with the host terminal'), - type = 'bool', + type = 'boolean', varname = 'p_termsync', }, { @@ -8828,7 +8828,7 @@ return { full_name = 'terse', scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -8910,7 +8910,7 @@ return { full_name = 'tildeop', scope = { 'global' }, short_desc = N_('tilde command "~" behaves like an operator'), - type = 'bool', + type = 'boolean', varname = 'p_to', }, { @@ -8925,7 +8925,7 @@ return { full_name = 'timeout', scope = { 'global' }, short_desc = N_('time out on mappings and key codes'), - type = 'bool', + type = 'boolean', varname = 'p_timeout', }, { @@ -8959,7 +8959,7 @@ return { full_name = 'title', scope = { 'global' }, short_desc = N_('Vim set the title of the window'), - type = 'bool', + type = 'boolean', varname = 'p_title', }, { @@ -9048,7 +9048,7 @@ return { redraw = { 'ui_option' }, scope = { 'global' }, short_desc = N_('out on mappings'), - type = 'bool', + type = 'boolean', varname = 'p_ttimeout', }, { @@ -9073,7 +9073,7 @@ return { no_mkrc = true, scope = { 'global' }, short_desc = N_('No description'), - type = 'bool', + type = 'boolean', immutable = true, }, { @@ -9129,7 +9129,7 @@ return { full_name = 'undofile', scope = { 'buffer' }, short_desc = N_('save undo information in a file'), - type = 'bool', + type = 'boolean', varname = 'p_udf', }, { @@ -9441,7 +9441,7 @@ return { full_name = 'visualbell', scope = { 'global' }, short_desc = N_('use visual bell instead of beeping'), - type = 'bool', + type = 'boolean', varname = 'p_vb', }, { @@ -9453,7 +9453,7 @@ return { full_name = 'warn', scope = { 'global' }, short_desc = N_('for shell command when buffer was changed'), - type = 'bool', + type = 'boolean', varname = 'p_warn', }, { @@ -9578,7 +9578,7 @@ return { full_name = 'wildignorecase', scope = { 'global' }, short_desc = N_('ignore case when completing file names'), - type = 'bool', + type = 'boolean', varname = 'p_wic', }, { @@ -9626,7 +9626,7 @@ return { full_name = 'wildmenu', scope = { 'global' }, short_desc = N_('use menu for command line completion'), - type = 'bool', + type = 'boolean', varname = 'p_wmnu', }, { @@ -9829,7 +9829,7 @@ return { redraw = { 'statuslines' }, scope = { 'window' }, short_desc = N_('keep window height when opening/closing windows'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'wfw', @@ -9843,7 +9843,7 @@ return { redraw = { 'statuslines' }, scope = { 'window' }, short_desc = N_('keep window width when opening/closing windows'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'wh', @@ -9996,7 +9996,7 @@ return { redraw = { 'current_window' }, scope = { 'window' }, short_desc = N_('lines wrap and continue on the next line'), - type = 'bool', + type = 'boolean', }, { abbreviation = 'wm', @@ -10027,7 +10027,7 @@ return { scope = { 'global' }, short_desc = N_('searches wrap around the end of the file'), tags = { 'E384', 'E385' }, - type = 'bool', + type = 'boolean', varname = 'p_ws', }, { @@ -10042,7 +10042,7 @@ return { full_name = 'write', scope = { 'global' }, short_desc = N_('to a file is allowed'), - type = 'bool', + type = 'boolean', varname = 'p_write', }, { @@ -10054,7 +10054,7 @@ return { full_name = 'writeany', scope = { 'global' }, short_desc = N_('write to file with no need for "!" override'), - type = 'bool', + type = 'boolean', varname = 'p_wa', }, { @@ -10077,7 +10077,7 @@ return { full_name = 'writebackup', scope = { 'global' }, short_desc = N_('make a backup before overwriting a file'), - type = 'bool', + type = 'boolean', varname = 'p_wb', }, { -- cgit From 165e5ececc25ce2d705efdd8ee6c8406884bf898 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 15 Dec 2023 06:42:29 +0800 Subject: vim-patch:17dca3cb97cd (#26584) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runtime(doc): grammar & typo fixes closes: vim/vim#13654 https://github.com/vim/vim/commit/17dca3cb97cdd7835e334b990565c8c0b93b1284 Co-authored-by: Dominique Pellé --- src/nvim/eval.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 51cf7bb0ea..a86ca9c1ea 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -7443,9 +7443,9 @@ M.funcs = { Date: Tue, 15 Aug 2023 18:47:14 +0800 Subject: feat(ui): completeopt support popup like vim --- src/nvim/api/keysets_defs.h | 5 ++ src/nvim/api/vim.c | 26 ++++++ src/nvim/buffer_defs.h | 3 +- src/nvim/eval.lua | 2 + src/nvim/insexpand.c | 28 ++++++ src/nvim/options.lua | 4 + src/nvim/optionstr.c | 2 +- src/nvim/popupmenu.c | 210 ++++++++++++++++++++++++++++++++++++++++---- src/nvim/popupmenu.h | 1 + src/nvim/window.c | 2 +- src/nvim/winfloat.c | 10 +++ 11 files changed, 273 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index c0daa0ca74..fa9a2cb013 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -346,3 +346,8 @@ typedef struct { LuaRef on_input; Boolean force_crlf; } Dict(open_term); + +typedef struct { + OptionalKeys is_set__complete_set_; + String info; +} Dict(complete_set); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2f3d527b9e..91f908bb88 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2300,3 +2300,29 @@ void nvim_error_event(uint64_t channel_id, Integer lvl, String data) // if we fork nvim processes as async workers ELOG("async error on channel %" PRId64 ": %s", channel_id, data.size ? data.data : ""); } + +/// Set info for the completion candidate index. +/// if the info was shown in a window, then the +/// window and buffer ids are returned for further +/// customization. If the text was not shown, an +/// empty dict is returned. +/// +/// @param index the completion candidate index +/// @param opts Optional parameters. +/// - info: (string) info text. +/// @return Dictionary containing these keys: +/// - winid: (number) floating window id +/// - bufnr: (number) buffer id in floating window +Dictionary nvim_complete_set(Integer index, Dict(complete_set) *opts) + FUNC_API_SINCE(12) +{ + Dictionary rv = ARRAY_DICT_INIT; + if (HAS_KEY(opts, complete_set, info)) { + win_T *wp = pum_set_info((int)index, opts->info.data); + if (wp) { + PUT(rv, "winid", WINDOW_OBJ(wp->handle)); + PUT(rv, "bufnr", BUFFER_OBJ(wp->w_buffer->handle)); + } + } + return rv; +} diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index beb3ec95b8..dc93243fad 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1286,7 +1286,8 @@ struct window_S { ScreenGrid w_grid; // the grid specific to the window ScreenGrid w_grid_alloc; // the grid specific to the window bool w_pos_changed; // true if window position changed - bool w_floating; ///< whether the window is floating + bool w_floating; ///< whether the window is floating + bool w_float_is_info; // the floating window is info float FloatConfig w_float_config; // w_fraction is the fractional row of the cursor within the window, from diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index a86ca9c1ea..984935d009 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -1373,6 +1373,8 @@ M.funcs = { no item is selected when using the or keys) inserted Inserted string. [NOT IMPLEMENTED YET] + preview_winid Info floating preview window id. + preview_bufnr Info floating preview buffer id. *complete_info_mode* mode values are: diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 8791aeb10c..54651eb48d 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -63,6 +63,7 @@ #include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" +#include "nvim/winfloat.h" // Definitions used for CTRL-X submode. // Note: If you change CTRL-X submode, you must also maintain ctrl_x_msgs[] @@ -1290,6 +1291,28 @@ void ins_compl_show_pum(void) } } +/// used for set or update info +void compl_set_info(int pum_idx) +{ + compl_T *comp = compl_first_match; + char *pum_text = compl_match_array[pum_idx].pum_text; + + while (comp != NULL) { + if (pum_text == comp->cp_str + || pum_text == comp->cp_text[CPT_ABBR]) { + comp->cp_text[CPT_INFO] = compl_match_array[pum_idx].pum_info; + + // if comp is current match update completed_item value + if (comp == compl_curr_match) { + dict_T *dict = ins_compl_dict_alloc(compl_curr_match); + set_vim_var_dict(VV_COMPLETED_ITEM, dict); + } + break; + } + comp = comp->cp_next; + } +} + #define DICT_FIRST (1) ///< use just first element in "dict" #define DICT_EXACT (2) ///< "dict" is the exact name of a file @@ -2813,6 +2836,11 @@ static void get_complete_info(list_T *what_list, dict_T *retdict) ret = tv_dict_add_nr(retdict, S_LEN("selected"), (compl_curr_match != NULL) ? compl_curr_match->cp_number - 1 : -1); + win_T *wp = win_float_find_preview(); + if (wp != NULL) { + tv_dict_add_nr(retdict, S_LEN("preview_winid"), wp->handle); + tv_dict_add_nr(retdict, S_LEN("preview_bufnr"), wp->w_buffer->handle); + } } (void)ret; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index edd7423e69..2621cc2eb1 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1450,6 +1450,10 @@ return { noselect Do not select a match in the menu, force the user to select one from the menu. Only works in combination with "menu" or "menuone". + + popup Show extra information about the currently selected + completion in a popup window. Only works in combination + with "menu" or "menuone". Overrides "preview". ]=], expand_cb = 'expand_set_completeopt', full_name = 'completeopt', diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 002cc68a3b..1aab9d4344 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -116,7 +116,7 @@ static char *(p_fdm_values[]) = { "manual", "expr", "marker", "indent", "syntax", "diff", NULL }; static char *(p_fcl_values[]) = { "all", NULL }; static char *(p_cot_values[]) = { "menu", "menuone", "longest", "preview", "noinsert", "noselect", - NULL }; + "popup", NULL }; #ifdef BACKSLASH_IN_FILENAME static char *(p_csl_values[]) = { "slash", "backslash", NULL }; #endif diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 56fc16a82e..a3e92fb595 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -8,8 +8,11 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/vim.h" #include "nvim/ascii_defs.h" +#include "nvim/autocmd.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/drawscreen.h" #include "nvim/eval/typval.h" @@ -29,6 +32,8 @@ #include "nvim/move.h" #include "nvim/option.h" #include "nvim/option_vars.h" +#include "nvim/optionstr.h" +#include "nvim/plines.h" #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" #include "nvim/state_defs.h" @@ -37,6 +42,7 @@ #include "nvim/ui_compositor.h" #include "nvim/vim_defs.h" #include "nvim/window.h" +#include "nvim/winfloat.h" static pumitem_T *pum_array = NULL; // items of displayed pum static int pum_size; // nr of items in "pum_array" @@ -654,6 +660,142 @@ void pum_redraw(void) } } +/// create a floting preview window for info +/// @return NULL when no enough room to show +static win_T *pum_create_float_preview(bool enter) +{ + FloatConfig config = FLOAT_CONFIG_INIT; + config.relative = kFloatRelativeEditor; + // when pum_above is SW otherwise is NW + config.anchor = pum_above ? kFloatAnchorSouth : 0; + int col = pum_col + pum_width + pum_scrollbar + 1; + // TODO(glepnir): support config align border by using completepopup + // align menu + config.row = pum_row; + int right_extra = Columns - col; + if (right_extra > 0) { + config.width = right_extra; + config.col = col - 1; + } else if (pum_col - 2 > 0) { + config.width = pum_col - 2; + config.col = pum_col - config.width - 1; + } else { + return NULL; + } + config.height = pum_height; + config.style = kWinStyleMinimal; + config.hide = true; + Error err = ERROR_INIT; + win_T *wp = win_new_float(NULL, true, config, &err); + // TODO(glepnir): remove win_enter usage + if (enter) { + win_enter(wp, false); + } + + // create a new buffer + Buffer b = nvim_create_buf(false, true, &err); + if (!b) { + win_free(wp, NULL); + return NULL; + } + buf_T *buf = find_buffer_by_handle(b, &err); + set_string_option_direct_in_buf(buf, kOptBufhidden, "wipe", OPT_FREE | OPT_LOCAL, 0); + wp->w_float_is_info = true; + wp->w_p_diff = false; + buf->b_p_bl = false; + win_set_buf(wp, buf, true, &err); + return wp; +} + +/// set info text to preview buffer. +static void pum_preview_set_text(buf_T *buf, char *info, linenr_T *lnum, int *max_width) +{ + for (char *p = info; *p != NUL;) { + int text_width = 0; + char *e = vim_strchr(p, '\n'); + if (e == NULL) { + ml_append_buf(buf, (*lnum)++, p, 0, false); + text_width = (int)mb_string2cells(p); + if (text_width > *max_width) { + *max_width = text_width; + } + break; + } + *e = NUL; + ml_append_buf(buf, (*lnum)++, p, (int)(e - p + 1), false); + text_width = (int)mb_string2cells(p); + if (text_width > *max_width) { + *max_width = text_width; + } + *e = '\n'; + p = e + 1; + } + // delete the empty last line + ml_delete_buf(buf, buf->b_ml.ml_line_count, false); +} + +/// adjust floating preview window width and height +static void pum_adjust_float_position(win_T *wp, int height, int width) +{ + // when floating window in right and right no enough room to show + // but left has enough room, adjust floating window to left. + if (wp->w_float_config.width < width && wp->w_float_config.col > pum_col) { + if ((pum_col - 2) > width) { + wp->w_float_config.width = width; + wp->w_float_config.col = pum_col - width - 1; + } + } + wp->w_float_config.width = MIN(wp->w_float_config.width, width); + wp->w_float_config.height = MIN(Rows, height); + wp->w_float_config.hide = false; + win_config_float(wp, wp->w_float_config); +} + +/// used in nvim_complete_set +win_T *pum_set_info(int pum_idx, char *info) +{ + if (!pum_is_visible || pum_idx < 0 || pum_idx > pum_size) { + return NULL; + } + pum_array[pum_idx].pum_info = xstrdup(info); + compl_set_info(pum_idx); + bool use_float = strstr(p_cot, "popup") != NULL ? true : false; + if (pum_idx != pum_selected || !use_float) { + return NULL; + } + + block_autocmds(); + RedrawingDisabled++; + no_u_sync++; + win_T *wp = win_float_find_preview(); + if (wp == NULL) { + wp = pum_create_float_preview(false); + // no enough room to show + if (!wp) { + return NULL; + } + } else { + // clean exist buffer + while (!buf_is_empty(wp->w_buffer)) { + ml_delete_buf(wp->w_buffer, (linenr_T)1, false); + } + } + no_u_sync--; + RedrawingDisabled--; + + linenr_T lnum = 0; + int max_info_width = 0; + pum_preview_set_text(wp->w_buffer, info, &lnum, &max_info_width); + redraw_later(wp, UPD_SOME_VALID); + + if (wp->w_p_wrap) { + lnum += plines_win(wp, lnum, true); + } + pum_adjust_float_position(wp, lnum, max_info_width); + unblock_autocmds(); + return wp; +} + /// Set the index of the currently selected item. The menu will scroll when /// necessary. When "n" is out of range don't scroll. /// This may be repeated when the preview window is used: @@ -670,6 +812,7 @@ static bool pum_set_selected(int n, int repeat) { int resized = false; int context = pum_height / 2; + int prev_selected = pum_selected; pum_selected = n; @@ -718,6 +861,10 @@ static bool pum_set_selected(int n, int repeat) pum_first = pum_selected + context - pum_height + 1; } } + // adjust for the number of lines displayed + if (pum_first > pum_size - pum_height) { + pum_first = pum_size - pum_height; + } // Show extra info in the preview window if there is something and // 'completeopt' contains "preview". @@ -730,6 +877,11 @@ static bool pum_set_selected(int n, int repeat) && (vim_strchr(p_cot, 'p') != NULL)) { win_T *curwin_save = curwin; tabpage_T *curtab_save = curtab; + bool use_float = strstr(p_cot, "popup") != NULL ? true : false; + + if (use_float) { + block_autocmds(); + } // Open a preview window. 3 lines by default. Prefer // 'previewheight' if set and smaller. @@ -742,12 +894,26 @@ static bool pum_set_selected(int n, int repeat) // Prevent undo sync here, if an autocommand syncs undo weird // things can happen to the undo tree. no_u_sync++; - resized = prepare_tagpreview(false); + + if (!use_float) { + resized = prepare_tagpreview(false); + } else { + win_T *wp = win_float_find_preview(); + if (wp) { + win_enter(wp, false); + } else { + wp = pum_create_float_preview(true); + if (wp) { + resized = true; + } + } + } + no_u_sync--; RedrawingDisabled--; g_do_tagpreview = 0; - if (curwin->w_p_pvw) { + if (curwin->w_p_pvw || curwin->w_float_is_info) { int res = OK; if (!resized && (curbuf->b_nwindows == 1) @@ -777,22 +943,11 @@ static bool pum_set_selected(int n, int repeat) if (res == OK) { linenr_T lnum = 0; - - for (char *p = pum_array[pum_selected].pum_info; *p != NUL;) { - char *e = vim_strchr(p, '\n'); - if (e == NULL) { - ml_append(lnum++, p, 0, false); - break; - } - *e = NUL; - ml_append(lnum++, p, (int)(e - p + 1), false); - *e = '\n'; - p = e + 1; - } - + int max_info_width = 0; + pum_preview_set_text(curbuf, pum_array[pum_selected].pum_info, &lnum, &max_info_width); // Increase the height of the preview window to show the // text, but no more than 'previewheight' lines. - if (repeat == 0) { + if (repeat == 0 && !use_float) { if (lnum > p_pvh) { lnum = (linenr_T)p_pvh; } @@ -805,9 +960,22 @@ static bool pum_set_selected(int n, int repeat) curbuf->b_changed = false; curbuf->b_p_ma = false; + if (pum_selected != prev_selected) { + curwin->w_topline = 1; + } else if (curwin->w_topline > curbuf->b_ml.ml_line_count) { + curwin->w_topline = curbuf->b_ml.ml_line_count; + } curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; + if (use_float) { + if (curwin->w_p_wrap) { + lnum += plines_win(curwin, lnum, true); + } + // adjust floting window by actually height and max info text width + pum_adjust_float_position(curwin, lnum, max_info_width); + } + if ((curwin != curwin_save && win_valid(curwin_save)) || (curtab != curtab_save && valid_tabpage(curtab_save))) { if (curtab != curtab_save && valid_tabpage(curtab_save)) { @@ -829,7 +997,7 @@ static bool pum_set_selected(int n, int repeat) // update the view on the buffer. Only go back to // the window when needed, otherwise it will always be // redrawn. - if (resized) { + if (resized && win_valid(curwin_save)) { no_u_sync++; win_enter(curwin_save, true); no_u_sync--; @@ -858,6 +1026,10 @@ static bool pum_set_selected(int n, int repeat) } } } + + if (use_float) { + unblock_autocmds(); + } } } @@ -892,6 +1064,10 @@ void pum_check_clear(void) } pum_is_drawn = false; pum_external = false; + win_T *wp = win_float_find_preview(); + if (wp != NULL) { + win_close(wp, false, false); + } } } diff --git a/src/nvim/popupmenu.h b/src/nvim/popupmenu.h index 24a3f8713a..dc741d1b77 100644 --- a/src/nvim/popupmenu.h +++ b/src/nvim/popupmenu.h @@ -2,6 +2,7 @@ #include +#include "nvim/buffer_defs.h" #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/grid_defs.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/window.c b/src/nvim/window.c index 98c62d6f44..618a3f760e 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4978,7 +4978,7 @@ void free_wininfo(wininfo_T *wip, buf_T *bp) /// Remove window 'wp' from the window list and free the structure. /// /// @param tp tab page "win" is in, NULL for current -static void win_free(win_T *wp, tabpage_T *tp) +void win_free(win_T *wp, tabpage_T *tp) { pmap_del(int)(&window_handles, wp->handle, NULL); clearFolding(wp); diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 0eea21eb9d..4efff3cfab 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -286,3 +286,13 @@ bool win_float_valid(const win_T *win) } return false; } + +win_T *win_float_find_preview(void) +{ + for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) { + if (wp->w_float_is_info) { + return wp; + } + } + return NULL; +} -- cgit From 19fed6bde176586b43b5b9ff37146ddf2f5a65ce Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 16 Dec 2023 21:30:08 +0800 Subject: vim-patch:9.0.2168: Moving tabpages on :drop may cause an endless loop (#26605) Problem: Moving tabpages on :drop may cause an endless loop Solution: Disallow moving tabpages on :drop when cleaning up the arglist first Moving tabpages during drop command may cause an endless loop When executing a :tab drop command, Vim will close all windows not in the argument list. This triggers various autocommands. If a user has created an 'au Tabenter * :tabmove -' autocommand, this can cause Vim to end up in an endless loop, when trying to iterate over all tabs (which would trigger the tabmove autocommand, which will change the tpnext pointer, etc). So instead of blocking all autocommands before we actually try to edit the given file, lets simply disallow to move tabpages around. Otherwise, we may change the expected number of events triggered during a :drop command, which users may rely on (there is actually a test, that expects various TabLeave/TabEnter autocommands) and would therefore be a backwards incompatible change. Don't make this an error, as this could trigger several times during the drop command, but silently ignore the :tabmove command in this case (and it should in fact finally trigger successfully when loading the given file in a new tab). So let's just be quiet here instead. fixes: vim/vim#13676 closes: vim/vim#13686 https://github.com/vim/vim/commit/df12e39b8b9dd39056e22b452276622cb7b617fd Co-authored-by: Christian Brabandt --- src/nvim/arglist.c | 4 ++++ src/nvim/autocmd.h | 4 ++-- src/nvim/window.c | 4 ++++ src/nvim/window.h | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index 541534abf9..064543b430 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -851,6 +851,9 @@ static void arg_all_close_unused_windows(arg_all_state_T *aall) if (aall->had_tab > 0) { goto_tabpage_tp(first_tabpage, true, true); } + + // moving tabpages around in an autocommand may cause an endless loop + tabpage_move_disallowed++; while (true) { win_T *wpnext = NULL; tabpage_T *tpnext = curtab->tp_next; @@ -950,6 +953,7 @@ static void arg_all_close_unused_windows(arg_all_state_T *aall) } goto_tabpage_tp(tpnext, true, true); } + tabpage_move_disallowed--; } /// Open up to "count" windows for the files in the argument list "aall->alist". diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index ea8f32feb2..b0a5a13026 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -28,8 +28,8 @@ EXTERN win_T *last_cursormoved_win INIT( = NULL); EXTERN pos_T last_cursormoved INIT( = { 0, 0, 0 }); EXTERN bool autocmd_busy INIT( = false); ///< Is apply_autocmds() busy? -EXTERN int autocmd_no_enter INIT( = false); ///< *Enter autocmds disabled -EXTERN int autocmd_no_leave INIT( = false); ///< *Leave autocmds disabled +EXTERN int autocmd_no_enter INIT( = false); ///< Buf/WinEnter autocmds disabled +EXTERN int autocmd_no_leave INIT( = false); ///< Buf/WinLeave autocmds disabled EXTERN bool did_filetype INIT( = false); ///< FileType event found /// value for did_filetype when starting to execute autocommands EXTERN bool keep_filetype INIT( = false); diff --git a/src/nvim/window.c b/src/nvim/window.c index 618a3f760e..0a09d8e27d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4426,6 +4426,10 @@ void tabpage_move(int nr) return; } + if (tabpage_move_disallowed) { + return; + } + int n = 1; tabpage_T *tp; diff --git a/src/nvim/window.h b/src/nvim/window.h index d70292508a..3c88965324 100644 --- a/src/nvim/window.h +++ b/src/nvim/window.h @@ -43,6 +43,8 @@ enum { LOWEST_WIN_ID = 1000, }; +EXTERN int tabpage_move_disallowed INIT( = 0); ///< moving tabpages around disallowed + /// Set to true if 'cmdheight' was explicitly set to 0. EXTERN bool p_ch_was_zero INIT( = false); -- cgit From 574519d9d68f7f28a868e95ef0d081cbae6ddec4 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Tue, 12 Dec 2023 18:07:45 +0200 Subject: feat(highlight): tweak default color scheme Problem: Updating default color scheme produced some feedback. Solution: Address the feedback. Outline of the changes: - Colors `Grey1` and `Grey2` are made a little bit more extreme (dark - darker, light - lighter) to increase overall contrast. - `gui` colors are treated as base with `cterm` colors falling back to using 0-15 colors which come from terminal emulator. - Update highlight group definition to not include attribute definition if it is intended to staty uncolored. - Tweak some specific highlight groups. - Add a list of Neovim specific highlight groups which are now defined differently in a breaking way. - Minor tweaks in several other places related to default color scheme. --- src/nvim/highlight_group.c | 313 ++++++++++++++++++++------------------------- 1 file changed, 142 insertions(+), 171 deletions(-) (limited to 'src') diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 4add1e3591..7c64571c11 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -135,24 +135,29 @@ static const char e_missing_argument_str[] // they still work when the runtime files can't be found. static const char *highlight_init_both[] = { - "Cursor guibg=fg guifg=bg", + "Cursor guifg=bg guibg=fg", "CursorLineNr gui=bold cterm=bold", - "QuickFixLine gui=bold cterm=bold", "RedrawDebugNormal gui=reverse cterm=reverse", "TabLineSel gui=bold cterm=bold", "TermCursor gui=reverse cterm=reverse", "Title gui=bold cterm=bold", + "Todo gui=bold cterm=bold", "Underlined gui=underline cterm=underline", - "lCursor guibg=fg guifg=bg", + "lCursor guifg=bg guibg=fg", + + "Constant guifg=NONE", + "Operator guifg=NONE", + "PreProc guifg=NONE", + "Type guifg=NONE", + "Delimiter guifg=NONE", // UI - "default link CurSearch Search", "default link CursorIM Cursor", "default link CursorLineFold FoldColumn", "default link CursorLineSign SignColumn", "default link EndOfBuffer NonText", "default link FloatBorder NormalFloat", - "default link FloatFooter Title", + "default link FloatFooter FloatTitle", "default link FloatTitle Title", "default link FoldColumn SignColumn", "default link IncSearch Search", @@ -167,6 +172,7 @@ static const char *highlight_init_both[] = { "default link PmenuKindSel PmenuSel", "default link PmenuSbar Pmenu", "default link Substitute Search", + "default link TabLine StatusLine", "default link TabLineFill TabLine", "default link TermCursorNC NONE", "default link VertSplit WinSeparator", @@ -203,6 +209,11 @@ static const char *highlight_init_both[] = { "default link SnippetTabstop Visual", // Diagnostic + "default link DiagnosticFloatingError DiagnosticError", + "default link DiagnosticFloatingWarn DiagnosticWarn", + "default link DiagnosticFloatingInfo DiagnosticInfo", + "default link DiagnosticFloatingHint DiagnosticHint", + "default link DiagnosticFloatingOk DiagnosticOk", "default link DiagnosticVirtualTextError DiagnosticError", "default link DiagnosticVirtualTextWarn DiagnosticWarn", "default link DiagnosticVirtualTextInfo DiagnosticInfo", @@ -293,162 +304,138 @@ static const char *highlight_init_both[] = { // Default colors only used with a light background. static const char *highlight_init_light[] = { - "Normal guifg=NvimDarkGrey2 ctermfg=234 guibg=NvimLightGrey2 ctermbg=253", + "Normal guifg=NvimDarkGrey2 guibg=NvimLightGrey2 ctermfg=NONE ctermbg=NONE", // UI - "ColorColumn guibg=NvimLightGrey4 ctermbg=247", - "Conceal guifg=NvimLightGrey4 ctermfg=247", - "CursorColumn guibg=NvimLightGrey3 ctermbg=251", - "CursorLine guibg=NvimLightGrey3 ctermbg=251", - "DiffAdd guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightGreen ctermbg=158", - "DiffChange guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightGrey4 ctermbg=247", - "DiffDelete guifg=NvimDarkRed ctermfg=52 gui=bold cterm=bold", - "DiffText guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightCyan ctermbg=123", - "Directory guifg=NvimDarkCyan ctermfg=30", - "ErrorMsg guifg=NvimDarkRed ctermfg=52", - "FloatShadow guibg=NvimLightGrey1 ctermbg=255 blend=80", - "FloatShadowThrough guibg=NvimLightGrey1 ctermbg=255 blend=100", - "Folded guifg=NvimDarkGrey4 ctermfg=239 guibg=NvimLightGrey3 ctermbg=251", - "LineNr guifg=NvimLightGrey4 ctermfg=247", - "MatchParen guibg=NvimLightGrey4 ctermbg=247 gui=bold cterm=bold", - "ModeMsg guifg=NvimDarkGreen ctermfg=22", - "MoreMsg guifg=NvimDarkCyan ctermfg=30", - "NonText guifg=NvimLightGrey4 ctermfg=247", - "NormalFloat guifg=NvimDarkGrey2 ctermfg=234 guibg=NvimLightGrey1 ctermbg=255", - "Pmenu guifg=NvimDarkGrey2 ctermfg=234 guibg=NvimLightGrey3 ctermbg=251", - "PmenuSel guifg=NvimLightGrey3 ctermfg=251 guibg=NvimDarkGrey2 ctermbg=234 blend=0", - "PmenuThumb guibg=NvimLightGrey4 ctermbg=247", - "Question guifg=NvimDarkCyan ctermfg=30", - "RedrawDebugClear guibg=NvimLightCyan ctermbg=123", - "RedrawDebugComposed guibg=NvimLightGreen ctermbg=158", - "RedrawDebugRecompose guibg=NvimLightRed ctermbg=217", - "Search guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightYellow ctermbg=222", - "SignColumn guifg=NvimLightGrey4 ctermfg=247", - "SpecialKey guifg=NvimLightGrey4 ctermfg=247", - "SpellBad guisp=NvimDarkRed gui=undercurl cterm=undercurl", - "SpellCap guisp=NvimDarkYellow gui=undercurl cterm=undercurl", - "SpellLocal guisp=NvimDarkGreen gui=undercurl cterm=undercurl", - "SpellRare guisp=NvimDarkCyan gui=undercurl cterm=undercurl", - "StatusLine guifg=NvimDarkGrey3 ctermfg=236 guibg=NvimLightGrey1 ctermbg=255", - "StatusLineNC guifg=NvimDarkGrey4 ctermfg=239 guibg=NvimLightGrey1 ctermbg=255", - "TabLine guifg=NvimDarkGrey3 ctermfg=236 guibg=NvimLightGrey1 ctermbg=255", - "Visual guibg=NvimLightGrey4 ctermbg=247", - "WarningMsg guifg=NvimDarkYellow ctermfg=52", // In 256 colors fall back to red + "ColorColumn guibg=NvimLightGrey4 cterm=reverse", + "Conceal guifg=NvimLightGrey4", + "CurSearch guifg=NvimLightGrey1 guibg=NvimDarkYellow ctermfg=15 ctermbg=3", + "CursorColumn guibg=NvimLightGrey3", + "CursorLine guibg=NvimLightGrey3", + "DiffAdd guifg=NvimDarkGrey1 guibg=NvimLightGreen ctermfg=15 ctermbg=2", + "DiffChange guifg=NvimDarkGrey1 guibg=NvimLightGrey4", + "DiffDelete guifg=NvimDarkRed gui=bold ctermfg=1 cterm=bold", + "DiffText guifg=NvimDarkGrey1 guibg=NvimLightCyan ctermfg=15 ctermbg=6", + "Directory guifg=NvimDarkCyan ctermfg=6", + "ErrorMsg guifg=NvimDarkRed ctermfg=1", + "FloatShadow guibg=NvimLightGrey4 ctermbg=0 blend=80", + "FloatShadowThrough guibg=NvimLightGrey4 ctermbg=0 blend=100", + "Folded guifg=NvimDarkGrey4 guibg=NvimLightGrey3", + "LineNr guifg=NvimLightGrey4", + "MatchParen guibg=NvimLightGrey4 gui=bold cterm=bold,underline", + "ModeMsg guifg=NvimDarkGreen ctermfg=2", + "MoreMsg guifg=NvimDarkCyan ctermfg=6", + "NonText guifg=NvimLightGrey4", + "NormalFloat guibg=NvimLightGrey1", + "Pmenu guibg=NvimLightGrey3 cterm=reverse", + "PmenuSel guifg=NvimLightGrey3 guibg=NvimDarkGrey2 cterm=reverse,underline blend=0", + "PmenuThumb guibg=NvimLightGrey4", + "Question guifg=NvimDarkCyan ctermfg=6", + "QuickFixLine guifg=NvimDarkCyan ctermfg=6", + "RedrawDebugClear guibg=NvimLightYellow ctermfg=15 ctermbg=3", + "RedrawDebugComposed guibg=NvimLightGreen ctermfg=15 ctermbg=2", + "RedrawDebugRecompose guibg=NvimLightRed ctermfg=15 ctermbg=1", + "Search guifg=NvimDarkGrey1 guibg=NvimLightYellow ctermfg=15 ctermbg=3", + "SignColumn guifg=NvimLightGrey4", + "SpecialKey guifg=NvimLightGrey4", + "SpellBad guisp=NvimDarkRed gui=undercurl cterm=undercurl", + "SpellCap guisp=NvimDarkYellow gui=undercurl cterm=undercurl", + "SpellLocal guisp=NvimDarkGreen gui=undercurl cterm=undercurl", + "SpellRare guisp=NvimDarkCyan gui=undercurl cterm=undercurl", + "StatusLine guifg=NvimDarkGrey3 guibg=NvimLightGrey1 cterm=reverse", + "StatusLineNC guifg=NvimDarkGrey4 guibg=NvimLightGrey1 cterm=bold", + "Visual guibg=NvimLightGrey4 ctermfg=15 ctermbg=0", + "WarningMsg guifg=NvimDarkYellow ctermfg=3", // Syntax - "Comment guifg=NvimDarkGrey4 ctermfg=239", - "Constant guifg=NvimDarkGrey2 ctermfg=234", - "String guifg=NvimDarkGreen ctermfg=22", - "Identifier guifg=NvimDarkBlue ctermfg=NONE", // No fallback in 256 colors to reduce noise - "Function guifg=NvimDarkCyan ctermfg=30", - "Statement guifg=NvimDarkGrey2 ctermfg=234 gui=bold cterm=bold", - "Operator guifg=NvimDarkGrey2 ctermfg=234", - "PreProc guifg=NvimDarkGrey2 ctermfg=234", - "Type guifg=NvimDarkGrey2 ctermfg=234", - "Special guifg=NvimDarkGrey2 ctermfg=234", - "Delimiter guifg=NvimDarkGrey2 ctermfg=234", - "Error guifg=NvimDarkGrey1 ctermfg=232 guibg=NvimLightRed ctermbg=217", - "Todo guifg=NvimDarkGrey1 ctermfg=232 gui=bold cterm=bold", + "Comment guifg=NvimDarkGrey4", + "String guifg=NvimDarkGreen ctermfg=2", + "Identifier guifg=NvimDarkBlue ctermfg=4", + "Function guifg=NvimDarkCyan ctermfg=6", + "Statement gui=bold cterm=bold", + "Special guifg=NvimDarkCyan ctermfg=6", + "Error guifg=NvimDarkGrey1 guibg=NvimLightRed ctermfg=15 ctermbg=1", // Diagnostic - "DiagnosticError guifg=NvimDarkRed ctermfg=52", - "DiagnosticWarn guifg=NvimDarkYellow ctermfg=52", // In 256 colors fall back to red - "DiagnosticInfo guifg=NvimDarkCyan ctermfg=30", - "DiagnosticHint guifg=NvimDarkBlue ctermfg=30", // In 256 colors fall back to cyan - "DiagnosticOk guifg=NvimDarkGreen ctermfg=22", + "DiagnosticError guifg=NvimDarkRed ctermfg=1", + "DiagnosticWarn guifg=NvimDarkYellow ctermfg=3", + "DiagnosticInfo guifg=NvimDarkCyan ctermfg=6", + "DiagnosticHint guifg=NvimDarkBlue ctermfg=4", + "DiagnosticOk guifg=NvimDarkGreen ctermfg=2", "DiagnosticUnderlineError guisp=NvimDarkRed gui=underline cterm=underline", "DiagnosticUnderlineWarn guisp=NvimDarkYellow gui=underline cterm=underline", "DiagnosticUnderlineInfo guisp=NvimDarkCyan gui=underline cterm=underline", - "DiagnosticUnderlineHint guisp=NvimDarkBlue gui=underline cterm=underline", // In 256 colors fall back to cyan + "DiagnosticUnderlineHint guisp=NvimDarkBlue gui=underline cterm=underline", "DiagnosticUnderlineOk guisp=NvimDarkGreen gui=underline cterm=underline", - "DiagnosticFloatingError guifg=NvimDarkRed ctermfg=52 guibg=NvimLightGrey1 ctermbg=255", - // In 256 colors fall back to red - "DiagnosticFloatingWarn guifg=NvimDarkYellow ctermfg=52 guibg=NvimLightGrey1 ctermbg=255", - "DiagnosticFloatingInfo guifg=NvimDarkCyan ctermfg=30 guibg=NvimLightGrey1 ctermbg=255", - // In 256 colors fall back to cyan - "DiagnosticFloatingHint guifg=NvimDarkBlue ctermfg=30 guibg=NvimLightGrey1 ctermbg=255", - "DiagnosticFloatingOk guifg=NvimDarkGreen ctermfg=22 guibg=NvimLightGrey1 ctermbg=255", "DiagnosticDeprecated guisp=NvimDarkRed gui=strikethrough cterm=strikethrough", NULL }; // Default colors only used with a dark background. static const char *highlight_init_dark[] = { - "Normal guifg=NvimLightGrey2 ctermfg=253 guibg=NvimDarkGrey2 ctermbg=234", + "Normal guifg=NvimLightGrey2 guibg=NvimDarkGrey2 ctermfg=NONE ctermbg=NONE", // UI - "ColorColumn guibg=NvimDarkGrey4 ctermbg=239", - "Conceal guifg=NvimDarkGrey4 ctermfg=239", - "CursorColumn guibg=NvimDarkGrey3 ctermbg=236", - "CursorLine guibg=NvimDarkGrey3 ctermbg=236", - "DiffAdd guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkGreen ctermbg=22", - "DiffChange guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkGrey4 ctermbg=239", - "DiffDelete guifg=NvimLightRed ctermfg=217 gui=bold cterm=bold", - "DiffText guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkCyan ctermbg=30", - "Directory guifg=NvimLightCyan ctermfg=123", - "ErrorMsg guifg=NvimLightRed ctermfg=217", - "FloatShadow guibg=NvimDarkGrey1 ctermbg=232 blend=80", - "FloatShadowThrough guibg=NvimDarkGrey1 ctermbg=232 blend=100", - "Folded guifg=NvimLightGrey4 ctermfg=247 guibg=NvimDarkGrey3 ctermbg=236", - "LineNr guifg=NvimDarkGrey4 ctermfg=239", - "MatchParen guibg=NvimDarkGrey4 ctermbg=239 gui=bold cterm=bold", - "ModeMsg guifg=NvimLightGreen ctermfg=158", - "MoreMsg guifg=NvimLightCyan ctermfg=123", - "NonText guifg=NvimDarkGrey4 ctermfg=239", - "NormalFloat guifg=NvimLightGrey2 ctermfg=253 guibg=NvimDarkGrey1 ctermbg=232", - "Pmenu guifg=NvimLightGrey2 ctermfg=253 guibg=NvimDarkGrey3 ctermbg=236", - "PmenuSel guifg=NvimDarkGrey3 ctermfg=236 guibg=NvimLightGrey2 ctermbg=253 blend=0", - "PmenuThumb guibg=NvimDarkGrey4 ctermbg=239", - "Question guifg=NvimLightCyan ctermfg=123", - "RedrawDebugClear guibg=NvimDarkCyan ctermbg=30", - "RedrawDebugComposed guibg=NvimDarkGreen ctermbg=22", - "RedrawDebugRecompose guibg=NvimDarkRed ctermbg=52", - "Search guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkYellow ctermbg=58", - "SignColumn guifg=NvimDarkGrey4 ctermfg=239", - "SpecialKey guifg=NvimDarkGrey4 ctermfg=239", - "SpellBad guisp=NvimLightRed gui=undercurl cterm=undercurl", - "SpellCap guisp=NvimLightYellow gui=undercurl cterm=undercurl", - "SpellLocal guisp=NvimLightGreen gui=undercurl cterm=undercurl", - "SpellRare guisp=NvimLightCyan gui=undercurl cterm=undercurl", - "StatusLine guifg=NvimLightGrey3 ctermfg=251 guibg=NvimDarkGrey1 ctermbg=232", - "StatusLineNC guifg=NvimLightGrey4 ctermfg=247 guibg=NvimDarkGrey1 ctermbg=232", - "TabLine guifg=NvimLightGrey3 ctermfg=251 guibg=NvimDarkGrey1 ctermbg=232", - "Visual guibg=NvimDarkGrey4 ctermbg=239", - "WarningMsg guifg=NvimLightYellow ctermfg=217", // In 256 colors fall back to red + "ColorColumn guibg=NvimDarkGrey4 cterm=reverse", + "Conceal guifg=NvimDarkGrey4", + "CurSearch guifg=NvimDarkGrey1 guibg=NvimLightYellow ctermfg=0 ctermbg=11", + "CursorColumn guibg=NvimDarkGrey3", + "CursorLine guibg=NvimDarkGrey3", + "DiffAdd guifg=NvimLightGrey1 guibg=NvimDarkGreen ctermfg=0 ctermbg=10", + "DiffChange guifg=NvimLightGrey1 guibg=NvimDarkGrey4", + "DiffDelete guifg=NvimLightRed gui=bold ctermfg=9 cterm=bold", + "DiffText guifg=NvimLightGrey1 guibg=NvimDarkCyan ctermfg=0 ctermbg=14", + "Directory guifg=NvimLightCyan ctermfg=14", + "ErrorMsg guifg=NvimLightRed ctermfg=9", + "FloatShadow guibg=NvimDarkGrey4 ctermbg=0 blend=80", + "FloatShadowThrough guibg=NvimDarkGrey4 ctermbg=0 blend=100", + "Folded guifg=NvimLightGrey4 guibg=NvimDarkGrey3", + "LineNr guifg=NvimDarkGrey4", + "MatchParen guibg=NvimDarkGrey4 gui=bold cterm=bold,underline", + "ModeMsg guifg=NvimLightGreen ctermfg=10", + "MoreMsg guifg=NvimLightCyan ctermfg=14", + "NonText guifg=NvimDarkGrey4", + "NormalFloat guibg=NvimDarkGrey1", + "Pmenu guibg=NvimDarkGrey3 cterm=reverse", + "PmenuSel guifg=NvimDarkGrey3 guibg=NvimLightGrey2 cterm=reverse,underline blend=0", + "PmenuThumb guibg=NvimDarkGrey4", + "Question guifg=NvimLightCyan ctermfg=14", + "QuickFixLine guifg=NvimLightCyan ctermfg=14", + "RedrawDebugClear guibg=NvimDarkYellow ctermfg=0 ctermbg=11", + "RedrawDebugComposed guibg=NvimDarkGreen ctermfg=0 ctermbg=10", + "RedrawDebugRecompose guibg=NvimDarkRed ctermfg=0 ctermbg=9", + "Search guifg=NvimLightGrey1 guibg=NvimDarkYellow ctermfg=0 ctermbg=11", + "SignColumn guifg=NvimDarkGrey4", + "SpecialKey guifg=NvimDarkGrey4", + "SpellBad guisp=NvimLightRed gui=undercurl cterm=undercurl", + "SpellCap guisp=NvimLightYellow gui=undercurl cterm=undercurl", + "SpellLocal guisp=NvimLightGreen gui=undercurl cterm=undercurl", + "SpellRare guisp=NvimLightCyan gui=undercurl cterm=undercurl", + "StatusLine guifg=NvimLightGrey3 guibg=NvimDarkGrey1 cterm=reverse", + "StatusLineNC guifg=NvimLightGrey4 guibg=NvimDarkGrey1 cterm=bold", + "Visual guibg=NvimDarkGrey4 ctermfg=0 ctermbg=15", + "WarningMsg guifg=NvimLightYellow ctermfg=11", // Syntax - "Comment guifg=NvimLightGrey4 ctermfg=247", - "Constant guifg=NvimLightGrey2 ctermfg=253", - "String guifg=NvimLightGreen ctermfg=158", - "Identifier guifg=NvimLightBlue ctermfg=NONE", // No fallback in 256 colors to reduce noise - "Function guifg=NvimLightCyan ctermfg=123", - "Statement guifg=NvimLightGrey2 ctermfg=253 gui=bold cterm=bold", - "Operator guifg=NvimLightGrey2 ctermfg=253", - "PreProc guifg=NvimLightGrey2 ctermfg=253", - "Type guifg=NvimLightGrey2 ctermfg=253", - "Special guifg=NvimLightGrey2 ctermfg=253", - "Delimiter guifg=NvimLightGrey2 ctermfg=253", - "Error guifg=NvimLightGrey1 ctermfg=255 guibg=NvimDarkRed ctermbg=52", - "Todo guifg=NvimLightGrey1 ctermfg=255 gui=bold cterm=bold", + "Comment guifg=NvimLightGrey4", + "String guifg=NvimLightGreen ctermfg=10", + "Identifier guifg=NvimLightBlue ctermfg=12", + "Function guifg=NvimLightCyan ctermfg=14", + "Statement gui=bold cterm=bold", + "Special guifg=NvimLightCyan ctermfg=14", + "Error guifg=NvimLightGrey1 guibg=NvimDarkRed ctermfg=0 ctermbg=9", // Diagnostic - "DiagnosticError guifg=NvimLightRed ctermfg=217", - "DiagnosticWarn guifg=NvimLightYellow ctermfg=217", // In 256 colors fall back to red - "DiagnosticInfo guifg=NvimLightCyan ctermfg=123", - "DiagnosticHint guifg=NvimLightBlue ctermfg=123", // In 256 colors fall back to cyan - "DiagnosticOk guifg=NvimLightGreen ctermfg=158", + "DiagnosticError guifg=NvimLightRed ctermfg=9", + "DiagnosticWarn guifg=NvimLightYellow ctermfg=11", + "DiagnosticInfo guifg=NvimLightCyan ctermfg=14", + "DiagnosticHint guifg=NvimLightBlue ctermfg=12", + "DiagnosticOk guifg=NvimLightGreen ctermfg=10", "DiagnosticUnderlineError guisp=NvimLightRed gui=underline cterm=underline", - "DiagnosticUnderlineWarn guisp=NvimLightYellow gui=underline cterm=underline", // In 256 colors fall back to red + "DiagnosticUnderlineWarn guisp=NvimLightYellow gui=underline cterm=underline", "DiagnosticUnderlineInfo guisp=NvimLightCyan gui=underline cterm=underline", "DiagnosticUnderlineHint guisp=NvimLightBlue gui=underline cterm=underline", "DiagnosticUnderlineOk guisp=NvimLightGreen gui=underline cterm=underline", - "DiagnosticFloatingError guifg=NvimLightRed ctermfg=217 guibg=NvimDarkGrey1 ctermbg=232", - // In 256 colors fall back to red - "DiagnosticFloatingWarn guifg=NvimLightYellow ctermfg=217 guibg=NvimDarkGrey1 ctermbg=232", - "DiagnosticFloatingInfo guifg=NvimLightCyan ctermfg=123 guibg=NvimDarkGrey1 ctermbg=232", - // In 256 colors fall back to cyan - "DiagnosticFloatingHint guifg=NvimLightBlue ctermfg=123 guibg=NvimDarkGrey1 ctermbg=232", - "DiagnosticFloatingOk guifg=NvimLightGreen ctermfg=158 guibg=NvimDarkGrey1 ctermbg=232", "DiagnosticDeprecated guisp=NvimLightRed gui=strikethrough cterm=strikethrough", NULL }; @@ -720,22 +707,6 @@ void init_highlight(bool both, bool reset) do_highlight(pp[i], reset, true); } - // Reverse looks ugly, but grey may not work for 8 colors. Thus let it - // depend on the number of colors available. - // With 8 colors brown is equal to yellow, need to use black for Search fg - // to avoid Statement highlighted text disappears. - // Clear the attributes, needed when changing the t_Co value. - if (t_colors > 8) { - do_highlight((*p_bg == 'l' - ? "Visual cterm=NONE ctermbg=LightGrey" - : "Visual cterm=NONE ctermbg=DarkGrey"), false, true); - } else { - do_highlight("Visual cterm=reverse ctermbg=NONE", false, true); - if (*p_bg == 'l') { - do_highlight("Search ctermfg=black", false, true); - } - } - syn_init_cmdline_highlight(false, false); } @@ -2890,26 +2861,26 @@ color_name_table_T color_name_table[] = { // Default Neovim palettes. // Dark/light palette is used for background in dark/light color scheme and // for foreground in light/dark color scheme. - { "NvimDarkBlue", RGB_(0x00, 0x50, 0x78) }, // cterm=24 - { "NvimDarkCyan", RGB_(0x00, 0x76, 0x76) }, // cterm=30 - { "NvimDarkGreen", RGB_(0x01, 0x58, 0x25) }, // cterm=22 - { "NvimDarkGrey1", RGB_(0x0a, 0x0b, 0x10) }, // cterm=232 - { "NvimDarkGrey2", RGB_(0x1c, 0x1d, 0x23) }, // cterm=234 - { "NvimDarkGrey3", RGB_(0x2c, 0x2e, 0x33) }, // cterm=236 - { "NvimDarkGrey4", RGB_(0x4f, 0x52, 0x58) }, // cterm=239 - { "NvimDarkMagenta", RGB_(0x4c, 0x00, 0x49) }, // cterm=53 - { "NvimDarkRed", RGB_(0x5e, 0x00, 0x09) }, // cterm=52 - { "NvimDarkYellow", RGB_(0x6e, 0x56, 0x00) }, // cterm=58 - { "NvimLightBlue", RGB_(0x9f, 0xd8, 0xff) }, // cterm=153 - { "NvimLightCyan", RGB_(0x83, 0xef, 0xef) }, // cterm=123 - { "NvimLightGreen", RGB_(0xaa, 0xed, 0xb7) }, // cterm=158 - { "NvimLightGrey1", RGB_(0xeb, 0xee, 0xf5) }, // cterm=255 - { "NvimLightGrey2", RGB_(0xd7, 0xda, 0xe1) }, // cterm=253 - { "NvimLightGrey3", RGB_(0xc4, 0xc6, 0xcd) }, // cterm=251 - { "NvimLightGrey4", RGB_(0x9b, 0x9e, 0xa4) }, // cterm=247 - { "NvimLightMagenta", RGB_(0xff, 0xc3, 0xfa) }, // cterm=189 - { "NvimLightRed", RGB_(0xff, 0xbc, 0xb5) }, // cterm=217 - { "NvimLightYellow", RGB_(0xf4, 0xd8, 0x8c) }, // cterm=222 + { "NvimDarkBlue", RGB_(0x00, 0x4c, 0x73) }, + { "NvimDarkCyan", RGB_(0x00, 0x73, 0x73) }, + { "NvimDarkGreen", RGB_(0x00, 0x55, 0x23) }, + { "NvimDarkGrey1", RGB_(0x07, 0x08, 0x0d) }, + { "NvimDarkGrey2", RGB_(0x14, 0x16, 0x1b) }, + { "NvimDarkGrey3", RGB_(0x2c, 0x2e, 0x33) }, + { "NvimDarkGrey4", RGB_(0x4f, 0x52, 0x58) }, + { "NvimDarkMagenta", RGB_(0x47, 0x00, 0x45) }, + { "NvimDarkRed", RGB_(0x59, 0x00, 0x08) }, + { "NvimDarkYellow", RGB_(0x6b, 0x53, 0x00) }, + { "NvimLightBlue", RGB_(0xa6, 0xdb, 0xff) }, + { "NvimLightCyan", RGB_(0x8c, 0xf8, 0xf7) }, + { "NvimLightGreen", RGB_(0xb3, 0xf6, 0xc0) }, + { "NvimLightGrey1", RGB_(0xee, 0xf1, 0xf8) }, + { "NvimLightGrey2", RGB_(0xe0, 0xe2, 0xea) }, + { "NvimLightGrey3", RGB_(0xc4, 0xc6, 0xcd) }, + { "NvimLightGrey4", RGB_(0x9b, 0x9e, 0xa4) }, + { "NvimLightMagenta", RGB_(0xff, 0xca, 0xff) }, + { "NvimLightRed", RGB_(0xff, 0xc0, 0xb9) }, + { "NvimLightYellow", RGB_(0xfc, 0xe0, 0x94) }, { "OldLace", RGB_(0xfd, 0xf5, 0xe6) }, { "Olive", RGB_(0x80, 0x80, 0x00) }, { "OliveDrab", RGB_(0x6b, 0x8e, 0x23) }, -- cgit From c18f3cfcdb8fc5a39b7c898eea619e3de94096b4 Mon Sep 17 00:00:00 2001 From: notomo Date: Sat, 16 Dec 2023 22:58:04 +0900 Subject: fix(api): crash after nvim_win_set_config title/footer validation error (#26606) --- src/nvim/api/win_config.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 856fac5585..4ffe3478d7 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -431,18 +431,36 @@ static bool parse_float_bufpos(Array bufpos, lpos_T *out) static void parse_bordertext(Object bordertext, BorderTextType bordertext_type, FloatConfig *fconfig, Error *err) { + if (bordertext.type != kObjectTypeString && bordertext.type != kObjectTypeArray) { + api_set_error(err, kErrorTypeValidation, "title/footer must be string or array"); + return; + } + + if (bordertext.type == kObjectTypeArray && bordertext.data.array.size == 0) { + api_set_error(err, kErrorTypeValidation, "title/footer cannot be an empty array"); + return; + } + bool *is_present; VirtText *chunks; int *width; int default_hl_id; switch (bordertext_type) { case kBorderTextTitle: + if (fconfig->title) { + clear_virttext(&fconfig->title_chunks); + } + is_present = &fconfig->title; chunks = &fconfig->title_chunks; width = &fconfig->title_width; default_hl_id = syn_check_group(S_LEN("FloatTitle")); break; case kBorderTextFooter: + if (fconfig->footer) { + clear_virttext(&fconfig->footer_chunks); + } + is_present = &fconfig->footer; chunks = &fconfig->footer_chunks; width = &fconfig->footer_width; @@ -462,16 +480,6 @@ static void parse_bordertext(Object bordertext, BorderTextType bordertext_type, return; } - if (bordertext.type != kObjectTypeArray) { - api_set_error(err, kErrorTypeValidation, "title must be string or array"); - return; - } - - if (bordertext.data.array.size == 0) { - api_set_error(err, kErrorTypeValidation, "title cannot be an empty array"); - return; - } - *width = 0; *chunks = parse_virt_text(bordertext.data.array, err, width); @@ -774,10 +782,6 @@ static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, return false; } - if (fconfig->title) { - clear_virttext(&fconfig->title_chunks); - } - parse_bordertext(config->title, kBorderTextTitle, fconfig, err); if (ERROR_SET(err)) { return false; @@ -801,10 +805,6 @@ static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, return false; } - if (fconfig->footer) { - clear_virttext(&fconfig->footer_chunks); - } - parse_bordertext(config->footer, kBorderTextFooter, fconfig, err); if (ERROR_SET(err)) { return false; -- cgit From 69f5f0e20e81ef3b6cb5ea011eda024e6e277acf Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 16 Dec 2023 15:03:22 +0100 Subject: vim-patch:82f19734bfcb runtime(doc): remove deprecation warning for gdefault Deprecated can be misunderstood as being slated for removal; slightly change wording to be clearer. https://github.com/vim/vim/commit/82f19734bfcbddbaee8d5d837f7b7a7119366020 Co-authored-by: dundargoc --- src/nvim/options.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 2621cc2eb1..7f3adb2b87 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -3350,9 +3350,9 @@ return { :s///g subst. one subst. all :s///gg subst. all subst. one - DEPRECATED: Setting this option may break plugins that are not aware - of this option. Also, many users get confused that adding the /g flag - has the opposite effect of that it normally does. + NOTE: Setting this option may break plugins that rely on the default + behavior of the 'g' flag. This will also make the 'g' flag have the + opposite effect of that documented in |:s_g|. ]=], full_name = 'gdefault', scope = { 'global' }, -- cgit From 7840760776cf8dbaa580ced87aec0222dbb693d7 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 14 Oct 2023 13:12:48 +0200 Subject: build: bump minimum cmake version to 3.13 The benefits are primarily being able to use FetchContent, which allows for a more flexible dependency handling. Other various quality-of-life features such as `-B` and `-S` flags are also included. This also removes broken `--version` generation as it does not work for version 3.10 and 3.11 due to the `JOIN` generator expression. Reference: https://github.com/neovim/neovim/issues/24004 --- src/nvim/CMakeLists.txt | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 2ccb8071c6..25287e89fa 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(main_lib INTERFACE) -add_executable(nvim main.c) +add_executable(nvim) set_target_properties(nvim PROPERTIES @@ -20,7 +20,7 @@ if(WIN32) target_compile_definitions(nlua0 PUBLIC LUA_BUILD_AS_DLL LUA_LIB) set_target_properties(nlua0 PROPERTIES ENABLE_EXPORTS TRUE) elseif(APPLE) - set_target_properties(nlua0 PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") + target_link_options(nlua0 PRIVATE -undefined dynamic_lookup) endif() find_package(Luv 1.43.0 REQUIRED) @@ -155,7 +155,7 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") # Actually export symbols - symbols may not be visible even though # ENABLE_EXPORTS is set to true. See # https://github.com/neovim/neovim/issues/25295 - set_target_properties(nvim PROPERTIES LINK_FLAGS "-Wl,-export_dynamic") + target_link_options(nvim PRIVATE "-Wl,-export_dynamic") elseif(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") target_link_libraries(main_lib INTERFACE pthread c++abi) elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS") @@ -348,10 +348,10 @@ set(LUA_KEYMAP_MODULE_SOURCE ${NVIM_RUNTIME_DIR}/lua/vim/keymap.lua) set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua) set(LUAJIT_RUNTIME_DIR ${DEPS_PREFIX}/share/luajit-2.1/jit) -glob_wrapper(UNICODE_FILES ${UNICODE_DIR}/*.txt) -glob_wrapper(API_HEADERS api/*.h) +file(GLOB UNICODE_FILES CONFIGURE_DEPENDS ${UNICODE_DIR}/*.txt) +file(GLOB API_HEADERS CONFIGURE_DEPENDS api/*.h) list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h) -glob_wrapper(MSGPACK_RPC_HEADERS msgpack_rpc/*.h) +file(GLOB MSGPACK_RPC_HEADERS CONFIGURE_DEPENDS msgpack_rpc/*.h) target_include_directories(main_lib INTERFACE ${GENERATED_DIR}) target_include_directories(main_lib INTERFACE ${CACHED_GENERATED_DIR}) @@ -367,12 +367,12 @@ file(MAKE_DIRECTORY ${TOUCHES_DIR}) file(MAKE_DIRECTORY ${GENERATED_DIR}) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}) -glob_wrapper(NVIM_SOURCES *.c) -glob_wrapper(NVIM_HEADERS *.h) -glob_wrapper(EXTERNAL_SOURCES ../xdiff/*.c ../mpack/*.c ../cjson/*.c ../klib/*.c ../termkey/*.c) -glob_wrapper(EXTERNAL_HEADERS ../xdiff/*.h ../mpack/*.h ../cjson/*.h ../klib/*.h ../termkey/*.h) +file(GLOB NVIM_SOURCES CONFIGURE_DEPENDS *.c) +file(GLOB NVIM_HEADERS CONFIGURE_DEPENDS *.h) +file(GLOB EXTERNAL_SOURCES CONFIGURE_DEPENDS ../xdiff/*.c ../mpack/*.c ../cjson/*.c ../klib/*.c ../termkey/*.c) +file(GLOB EXTERNAL_HEADERS CONFIGURE_DEPENDS ../xdiff/*.h ../mpack/*.h ../cjson/*.h ../klib/*.h ../termkey/*.h) -glob_wrapper(NLUA0_SOURCES ../mpack/*.c) +file(GLOB NLUA0_SOURCES CONFIGURE_DEPENDS ../mpack/*.c) if(PREFER_LUA) # luajit not used, use a vendored copy of the bit module @@ -398,8 +398,8 @@ foreach(subdir file(MAKE_DIRECTORY ${GENERATED_DIR}/${subdir}) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir}) - glob_wrapper(sources ${subdir}/*.c) - glob_wrapper(headers ${subdir}/*.h) + file(GLOB sources CONFIGURE_DEPENDS ${subdir}/*.c) + file(GLOB headers CONFIGURE_DEPENDS ${subdir}/*.h) list(APPEND NVIM_SOURCES ${sources}) list(APPEND NVIM_HEADERS ${headers}) endforeach() @@ -432,10 +432,10 @@ list(REMOVE_ITEM NVIM_SOURCES ${to_remove}) # xdiff, mpack, lua-cjson, termkey: inlined external project, we don't maintain it. #9306 if(MSVC) set_source_files_properties( - ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -wd4090 -wd4244 -wd4267") + ${EXTERNAL_SOURCES} PROPERTIES COMPILE_OPTIONS "-wd4090;-wd4244;-wd4267") else() set_source_files_properties( - ${EXTERNAL_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion -Wno-missing-noreturn -Wno-missing-format-attribute -Wno-double-promotion -Wno-strict-prototypes -Wno-misleading-indentation -Wno-sign-compare -Wno-implicit-fallthrough -Wno-missing-prototypes -Wno-missing-field-initializers") + ${EXTERNAL_SOURCES} PROPERTIES COMPILE_OPTIONS "-Wno-conversion;-Wno-missing-noreturn;-Wno-missing-format-attribute;-Wno-double-promotion;-Wno-strict-prototypes;-Wno-misleading-indentation;-Wno-sign-compare;-Wno-implicit-fallthrough;-Wno-missing-prototypes;-Wno-missing-field-initializers") endif() # Log level (NVIM_LOG_DEBUG in log.h) @@ -685,7 +685,7 @@ endforeach() if(PREFER_LUA) message(STATUS "luajit not used, skipping unit tests") else() - glob_wrapper(UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c) + file(GLOB UNIT_TEST_FIXTURES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c) target_sources(nvim PRIVATE ${UNIT_TEST_FIXTURES}) target_compile_definitions(nvim PRIVATE UNIT_TESTING) endif() @@ -764,7 +764,7 @@ file(MAKE_DIRECTORY ${BINARY_LIB_DIR}) # install treesitter parser if bundled if(EXISTS ${DEPS_PREFIX}/lib/nvim/parser) - glob_wrapper(TREESITTER_PARSERS ${DEPS_PREFIX}/lib/nvim/parser/*) + file(GLOB TREESITTER_PARSERS CONFIGURE_DEPENDS ${DEPS_PREFIX}/lib/nvim/parser/*) foreach(parser_lib ${TREESITTER_PARSERS}) file(COPY ${parser_lib} DESTINATION ${BINARY_LIB_DIR}/parser) endforeach() @@ -910,9 +910,9 @@ set(VIMDOC_FILES ${NVIM_RUNTIME_DIR}/doc/treesitter.txt ) -glob_wrapper(API_SOURCES ${PROJECT_SOURCE_DIR}/src/nvim/api/*.c) +file(GLOB API_SOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/nvim/api/*.c) -glob_wrapper(LUA_SOURCES +file(GLOB LUA_SOURCES CONFIGURE_DEPENDS ${NVIM_RUNTIME_DIR}/lua/vim/*.lua ${NVIM_RUNTIME_DIR}/lua/vim/filetype/*.lua ${NVIM_RUNTIME_DIR}/lua/vim/lsp/*.lua -- cgit From 8fb7419d7c5e2df3b792d18fa56f973088e69be2 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Sat, 16 Dec 2023 11:18:45 -0600 Subject: refactor: only reload colorscheme if &bg changed (#26598) Currently, setting &bg at all re-initializes highlights and reloads the active colorscheme, even if the actual value of &bg has not changed. With https://github.com/neovim/neovim/pull/26595 this causes a regression since &bg is set unconditionally based on the value detected from the terminal. Instead, only reload the colorscheme if the actual value of &bg has changed. --- src/nvim/options.lua | 8 ++------ src/nvim/optionstr.c | 7 ++++++- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 7f3adb2b87..6d61a6d64e 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -316,7 +316,7 @@ return { See |:hi-normal| if you want to set the background color explicitly. *g:colors_name* When a color scheme is loaded (the "g:colors_name" variable is set) - setting 'background' will cause the color scheme to be reloaded. If + changing 'background' will cause the color scheme to be reloaded. If the color scheme adjusts to the value of 'background' this will work. However, if the color scheme sets 'background' itself the effect may be undone. First delete the "g:colors_name" variable when needed. @@ -326,13 +326,9 @@ return { :if $TERM ==# "xterm" : set background=dark :endif - < When this option is set, the default settings for the highlight groups + < When this option is changed, the default settings for the highlight groups will change. To use other settings, place ":highlight" commands AFTER the setting of the 'background' option. - This option is also used in the "$VIMRUNTIME/syntax/syntax.vim" file - to select the colors for syntax highlighting. After changing this - option, you must load syntax.vim again to see the result. This can be - done with ":syntax on". ]=], expand_cb = 'expand_set_background', full_name = 'background', diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 1aab9d4344..9ca8615467 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -663,12 +663,17 @@ int expand_set_ambiwidth(optexpand_T *args, int *numMatches, char ***matches) } /// The 'background' option is changed. -const char *did_set_background(optset_T *args FUNC_ATTR_UNUSED) +const char *did_set_background(optset_T *args) { if (check_opt_strings(p_bg, p_bg_values, false) != OK) { return e_invarg; } + if (args->os_oldval.string.data[0] == *p_bg) { + // Value was not changed + return NULL; + } + int dark = (*p_bg == 'd'); init_highlight(false, false); -- cgit From 404fdb0f3683094c2d40e1ee7e41d5c491f41a06 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 24 Nov 2023 13:28:15 +0100 Subject: build: cmake fixes - add EXTERNALPROJECT_OPTIONS variable to main build - use `REQUIRED` keyword for IWYU. - remove check_c_compiler_flag checks when `ENABLE_COMPILER_SUGGESTIONS` is `ON`. If we explicitly enable it then we probably want it to give an error if it doesn't exist, rather than silently skip it. - Move dependency interface libraries to their find module and use them as a pseudo-imported target. - Remove BUSTED_OUTPUT_TYPE. It's not used and we can reintroduce it again if something similar is needed. - Use LINK_OPTIONS intead of LINK_FLAGS when generating the `--version` output. --- src/nvim/CMakeLists.txt | 92 +++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 25287e89fa..3773168948 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -10,11 +10,6 @@ set_target_properties(nvim # Dependencies #------------------------------------------------------------------------------- -add_library(libuv INTERFACE) -find_package(Libuv 1.28.0 REQUIRED) -target_include_directories(libuv SYSTEM BEFORE INTERFACE ${LIBUV_INCLUDE_DIR}) -target_link_libraries(libuv INTERFACE ${LIBUV_LIBRARIES}) - add_library(nlua0 MODULE) if(WIN32) target_compile_definitions(nlua0 PUBLIC LUA_BUILD_AS_DLL LUA_LIB) @@ -23,33 +18,31 @@ elseif(APPLE) target_link_options(nlua0 PRIVATE -undefined dynamic_lookup) endif() +# TODO(dundargoc): unittest stops working if I create an pseudo-imported +# library "luv" as with the other dependencies. Figure out why and fix. find_package(Luv 1.43.0 REQUIRED) target_include_directories(main_lib SYSTEM BEFORE INTERFACE ${LUV_INCLUDE_DIR}) target_link_libraries(main_lib INTERFACE ${LUV_LIBRARY}) find_package(Iconv REQUIRED) -find_package(Lpeg REQUIRED) +find_package(Libintl REQUIRED) # Libintl (not Intl) selects our FindLibintl.cmake script. #8464 +find_package(Libuv 1.28.0 REQUIRED) find_package(Libvterm 0.3.3 REQUIRED) +find_package(Lpeg REQUIRED) find_package(Msgpack 1.0.0 REQUIRED) find_package(Treesitter 0.20.8 REQUIRED) find_package(Unibilium 2.0 REQUIRED) target_link_libraries(main_lib INTERFACE iconv + libintl libvterm + lpeg msgpack treesitter - unibilium - lpeg) + unibilium) target_link_libraries(nlua0 PUBLIC lpeg) -# Libintl (not Intl) selects our FindLibintl.cmake script. #8464 -find_package(Libintl REQUIRED) -target_include_directories(main_lib SYSTEM BEFORE INTERFACE ${LIBINTL_INCLUDE_DIR}) -if (LIBINTL_LIBRARY) - target_link_libraries(main_lib INTERFACE ${LIBINTL_LIBRARY}) -endif() - target_compile_definitions(main_lib INTERFACE HAVE_UNIBILIUM) # The unit test lib requires LuaJIT; it will be skipped if LuaJIT is missing. @@ -218,7 +211,9 @@ if(ENABLE_ASAN_UBSAN) target_compile_options(nvim PRIVATE -fsanitize=address) target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined) target_compile_definitions(nvim PRIVATE ENABLE_ASAN_UBSAN) -elseif(ENABLE_MSAN) +endif() + +if(ENABLE_MSAN) message(STATUS "Enabling memory sanitizer for nvim.") target_compile_options(nvim PRIVATE -fsanitize=memory @@ -226,7 +221,9 @@ elseif(ENABLE_MSAN) -fno-omit-frame-pointer -fno-optimize-sibling-calls) target_link_libraries(nvim PRIVATE -fsanitize=memory -fsanitize-memory-track-origins) -elseif(ENABLE_TSAN) +endif() + +if(ENABLE_TSAN) message(STATUS "Enabling thread sanitizer for nvim.") target_compile_options(nvim PRIVATE -fsanitize=thread -fPIE) target_link_libraries(nvim PRIVATE -fsanitize=thread) @@ -244,11 +241,7 @@ endif() option(ENABLE_IWYU "Run include-what-you-use with the compiler." OFF) if(ENABLE_IWYU) - find_program(IWYU_PRG NAMES include-what-you-use iwyu) - if(NOT IWYU_PRG) - message(FATAL_ERROR "ENABLE_IWYU is ON but include-what-you-use is not found!") - endif() - + find_program(IWYU_PRG NAMES include-what-you-use iwyu REQUIRED) set(iwyu_flags "${IWYU_PRG};") string(APPEND iwyu_flags "-Xiwyu;--no_default_mappings;") string(APPEND iwyu_flags "-Xiwyu;--no_fwd_decls;") @@ -260,26 +253,11 @@ endif() option(ENABLE_COMPILER_SUGGESTIONS "Enable -Wsuggest compiler warnings" OFF) if(ENABLE_COMPILER_SUGGESTIONS) - # Clang doesn't have -Wsuggest-attribute so check for each one. - check_c_compiler_flag(-Wsuggest-attribute=pure HAVE_WSUGGEST_ATTRIBUTE_PURE) - if(HAVE_WSUGGEST_ATTRIBUTE_PURE) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=pure) - endif() - - check_c_compiler_flag(-Wsuggest-attribute=const HAVE_WSUGGEST_ATTRIBUTE_CONST) - if(HAVE_WSUGGEST_ATTRIBUTE_CONST) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=const) - endif() - - check_c_compiler_flag(-Wsuggest-attribute=malloc HAVE_WSUGGEST_ATTRIBUTE_MALLOC) - if(HAVE_WSUGGEST_ATTRIBUTE_MALLOC) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=malloc) - endif() - - check_c_compiler_flag(-Wsuggest-attribute=cold HAVE_WSUGGEST_ATTRIBUTE_COLD) - if(HAVE_WSUGGEST_ATTRIBUTE_COLD) - target_compile_options(main_lib INTERFACE -Wsuggest-attribute=cold) - endif() + target_compile_options(main_lib INTERFACE + -Wsuggest-attribute=cold + -Wsuggest-attribute=const + -Wsuggest-attribute=malloc + -Wsuggest-attribute=pure) endif() option(ENABLE_GCOV "Enable gcov support" OFF) @@ -353,19 +331,19 @@ file(GLOB API_HEADERS CONFIGURE_DEPENDS api/*.h) list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h) file(GLOB MSGPACK_RPC_HEADERS CONFIGURE_DEPENDS msgpack_rpc/*.h) -target_include_directories(main_lib INTERFACE ${GENERATED_DIR}) -target_include_directories(main_lib INTERFACE ${CACHED_GENERATED_DIR}) -target_include_directories(main_lib INTERFACE ${GENERATED_INCLUDES_DIR}) -target_include_directories(main_lib INTERFACE "${PROJECT_BINARY_DIR}/cmake.config") -target_include_directories(main_lib INTERFACE "${PROJECT_SOURCE_DIR}/src") +target_include_directories(main_lib INTERFACE + ${GENERATED_DIR} + ${CACHED_GENERATED_DIR} + ${GENERATED_INCLUDES_DIR} + "${PROJECT_BINARY_DIR}/cmake.config" + "${PROJECT_SOURCE_DIR}/src") -target_include_directories(nlua0 PUBLIC "${PROJECT_SOURCE_DIR}/src") -target_include_directories(nlua0 PUBLIC "${PROJECT_BINARY_DIR}/cmake.config") -target_include_directories(nlua0 PUBLIC ${GENERATED_INCLUDES_DIR}) +target_include_directories(nlua0 PUBLIC + "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_BINARY_DIR}/cmake.config" + ${GENERATED_INCLUDES_DIR}) -file(MAKE_DIRECTORY ${TOUCHES_DIR}) -file(MAKE_DIRECTORY ${GENERATED_DIR}) -file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}) +file(MAKE_DIRECTORY ${TOUCHES_DIR} ${GENERATED_DIR} ${GENERATED_INCLUDES_DIR}) file(GLOB NVIM_SOURCES CONFIGURE_DEPENDS *.c) file(GLOB NVIM_HEADERS CONFIGURE_DEPENDS *.h) @@ -885,6 +863,10 @@ add_dependencies(uncrustify_update_config uncrustify) add_custom_target(lintc) add_dependencies(lintc lintc-clint lintc-uncrustify lintc-clang-tidy) +#------------------------------------------------------------------------------- +# Docs +#------------------------------------------------------------------------------- + add_custom_target(generated-sources DEPENDS ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS} @@ -893,10 +875,6 @@ add_custom_target(generated-sources DEPENDS add_subdirectory(po) -#------------------------------------------------------------------------------- -# Docs -#------------------------------------------------------------------------------- - set(VIMDOC_FILES ${NVIM_RUNTIME_DIR}/doc/api.mpack ${NVIM_RUNTIME_DIR}/doc/api.txt -- cgit From 8f08b1efbd096850c04c2e8e2890d993bd4d9f95 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sun, 17 Dec 2023 05:23:33 +0600 Subject: refactor(options): use hashy for finding options (#26573) Problem: `findoption()` searches through the options[] table linearly for option names, even though hashy can be used to generate a compile-time hash table for it. Solution: Use hashy to generate a compile time hash table for finding options. This also allows handling option aliases, so we don't need separate options[] table entries for things like 'viminfo'. --- src/nvim/CMakeLists.txt | 13 +++- src/nvim/api/deprecated.c | 4 +- src/nvim/api/options.c | 2 +- src/nvim/eval/vars.c | 2 +- src/nvim/generators/gen_options.lua | 19 +---- src/nvim/generators/gen_options_enum.lua | 76 +++++++++++++++++++ src/nvim/option.c | 122 +++++++------------------------ src/nvim/option.h | 2 +- src/nvim/options.lua | 20 +---- src/nvim/statusline.c | 2 +- 10 files changed, 124 insertions(+), 138 deletions(-) create mode 100644 src/nvim/generators/gen_options_enum.lua (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 3773168948..a21a87ad5e 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -303,10 +303,12 @@ set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h) set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h) set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h) set(GENERATED_OPTIONS_ENUM ${GENERATED_DIR}/options_enum.generated.h) +set(GENERATED_OPTIONS_MAP ${GENERATED_DIR}/options_map.generated.h) set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua) set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua) set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua) set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua) +set(OPTIONS_ENUM_GENERATOR ${GENERATOR_DIR}/gen_options_enum.lua) set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua) set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/src/unicode) set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h) @@ -615,6 +617,7 @@ list(APPEND NVIM_GENERATED_FOR_HEADERS "${GENERATED_EX_CMDS_ENUM}" "${GENERATED_EVENTS_ENUM}" "${GENERATED_KEYSETS_DEFS}" + "${GENERATED_OPTIONS_ENUM}" ) list(APPEND NVIM_GENERATED_FOR_SOURCES @@ -622,6 +625,7 @@ list(APPEND NVIM_GENERATED_FOR_SOURCES "${GENERATED_EX_CMDS_DEFS}" "${GENERATED_EVENTS_NAMES_MAP}" "${GENERATED_OPTIONS}" + "${GENERATED_OPTIONS_MAP}" "${GENERATED_UNICODE_TABLES}" "${VIM_MODULE_FILE}" ) @@ -647,11 +651,16 @@ add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} DEPENDS ${LUA_GEN_DEPS} ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua ) -add_custom_command(OUTPUT ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} - COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} +add_custom_command(OUTPUT ${GENERATED_OPTIONS} + COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua ) +add_custom_command(OUTPUT ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} + COMMAND ${LUA_GEN} ${OPTIONS_ENUM_GENERATOR} ${GENERATED_OPTIONS_ENUM} ${GENERATED_OPTIONS_MAP} + DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_ENUM_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua +) + # NVIM_GENERATED_FOR_SOURCES and NVIM_GENERATED_FOR_HEADERS must be mutually exclusive. foreach(hfile ${NVIM_GENERATED_FOR_HEADERS}) list(FIND NVIM_GENERATED_FOR_SOURCES ${hfile} hfile_idx) diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 371361c5a1..27af581ef4 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -643,7 +643,7 @@ static Object get_option_from(void *from, OptReqScope req_scope, String name, Er return (Object)OBJECT_INIT; }); - OptVal value = get_option_value_strict(findoption(name.data), req_scope, from, err); + OptVal value = get_option_value_strict(find_option(name.data), req_scope, from, err); if (ERROR_SET(err)) { return (Object)OBJECT_INIT; } @@ -669,7 +669,7 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, return; }); - OptIndex opt_idx = findoption(name.data); + OptIndex opt_idx = find_option(name.data); VALIDATE_S(opt_idx != kOptInvalid, "option name", name.data, { return; }); diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 54a2fbf385..a3ea7d9d47 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -79,7 +79,7 @@ static int validate_option_value_args(Dict(option) *opts, char *name, OptIndex * return FAIL; }); - *opt_idxp = findoption(name); + *opt_idxp = find_option(name); int flags = get_option_attrs(*opt_idxp); if (flags == 0) { // hidden or unknown option diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 6fd707a0b0..9897ca77f1 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -1943,7 +1943,7 @@ typval_T optval_as_tv(OptVal value, bool numbool) /// Set option "varname" to the value of "varp" for the current buffer/window. static void set_option_from_tv(const char *varname, typval_T *varp) { - OptIndex opt_idx = findoption(varname); + OptIndex opt_idx = find_option(varname); if (opt_idx == kOptInvalid) { semsg(_(e_unknown_option2), varname); return; diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 61d5df3c84..2fd11e4c58 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -1,5 +1,4 @@ local options_file = arg[1] -local options_enum_file = arg[2] local opt_fd = assert(io.open(options_file, 'w')) @@ -171,7 +170,7 @@ local function dump_option(i, o) end if o.varname then w(' .var=&' .. o.varname) - -- Immutable options should directly point to the default value + -- Immutable options can directly point to the default value. elseif o.immutable then w((' .var=&options[%u].def_val'):format(i - 1)) elseif #o.scope == 1 and o.scope[1] == 'window' then @@ -248,19 +247,3 @@ w('') for _, v in ipairs(defines) do w('#define ' .. v[1] .. ' ' .. v[2]) end - --- Generate options enum file -opt_fd = assert(io.open(options_enum_file, 'w')) - -w('typedef enum {') -w(' kOptInvalid = -1,') - -for i, o in ipairs(options.options) do - w((' kOpt%s = %u,'):format(lowercase_to_titlecase(o.full_name), i - 1)) -end - -w(' // Option count, used when iterating through options') -w('#define kOptIndexCount ' .. tostring(#options.options)) -w('} OptIndex;') - -opt_fd:close() diff --git a/src/nvim/generators/gen_options_enum.lua b/src/nvim/generators/gen_options_enum.lua new file mode 100644 index 0000000000..c3fe9baae6 --- /dev/null +++ b/src/nvim/generators/gen_options_enum.lua @@ -0,0 +1,76 @@ +-- Generates option index enum and map of option name to option index. +-- Handles option full name, short name and aliases. + +local options_enum_file = arg[1] +local options_map_file = arg[2] +local options_enum_fd = assert(io.open(options_enum_file, 'w')) +local options_map_fd = assert(io.open(options_map_file, 'w')) + +--- @param s string +local function enum_w(s) + options_enum_fd:write(s .. '\n') +end + +--- @param s string +local function map_w(s) + options_map_fd:write(s .. '\n') +end + +--- @param s string +--- @return string +local lowercase_to_titlecase = function(s) + return s:sub(1, 1):upper() .. s:sub(2) +end + +--- @type vim.option_meta[] +local options = require('options').options +--- @type { [string]: string } +local option_index = {} + +-- Generate option index enum and populate the `option_index` dictionary. +enum_w('typedef enum {') +enum_w(' kOptInvalid = -1,') + +for i, o in ipairs(options) do + local enum_val_name = 'kOpt' .. lowercase_to_titlecase(o.full_name) + enum_w((' %s = %u,'):format(enum_val_name, i - 1)) + + option_index[o.full_name] = enum_val_name + + if o.abbreviation then + option_index[o.abbreviation] = enum_val_name + end + + if o.alias then + o.alias = type(o.alias) == 'string' and { o.alias } or o.alias + + for _, v in ipairs(o.alias) do + option_index[v] = enum_val_name + end + end +end + +enum_w(' // Option count, used when iterating through options') +enum_w('#define kOptIndexCount ' .. tostring(#options)) +enum_w('} OptIndex;') +enum_w('') + +options_enum_fd:close() + +--- Generate option index map. +local hashy = require('generators.hashy') +local neworder, hashfun = hashy.hashy_hash('find_option', vim.tbl_keys(option_index), function(idx) + return ('option_hash_elems[%s].name'):format(idx) +end) + +map_w('static const struct { const char *name; OptIndex opt_idx; } option_hash_elems[] = {') + +for _, name in ipairs(neworder) do + assert(option_index[name] ~= nil) + map_w((' { .name = "%s", .opt_idx = %s },'):format(name, option_index[name])) +end + +map_w('};\n') +map_w('static ' .. hashfun) + +options_map_fd:close() diff --git a/src/nvim/option.c b/src/nvim/option.c index 1f4f547759..0d0437d45f 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1,8 +1,8 @@ // User-settable options. Checklist for adding a new option: // - Put it in options.lua -// - For a global option: Add a variable for it in option_defs.h. +// - For a global option: Add a variable for it in option_vars.h. // - For a buffer or window local option: -// - Add a BV_XX or WV_XX entry to option_defs.h +// - Add a BV_XX or WV_XX entry to option_vars.h // - Add a variable to the window or buffer struct in buffer_defs.h. // - For a window option, add some code to copy_winopt(). // - For a window string option, add code to check_winopt() @@ -12,7 +12,7 @@ // - For a buffer string option, add code to check_buf_options(). // - If it's a numeric option, add any necessary bounds checks to check_num_option_bounds(). // - If it's a list of flags, add some code in do_set(), search for WW_ALL. -// - Add documentation! doc/options.txt, and any other related places. +// - Add documentation! "desc" in options.lua, and any other related places. // - Add an entry in runtime/optwin.vim. #define IN_OPTION_C @@ -143,15 +143,13 @@ typedef enum { # include "option.c.generated.h" #endif -// options[] is initialized here. -// The order of the options MUST be alphabetic for ":set all" and findoption(). -// All option names MUST start with a lowercase letter (for findoption()). -// Exception: "t_" options are at the end. +// options[] is initialized in options.generated.h. // The options with a NULL variable are 'hidden': a set command for them is // ignored and they are not printed. #ifdef INCLUDE_GENERATED_DECLARATIONS # include "options.generated.h" +# include "options_map.generated.h" #endif static int p_bin_dep_opts[] = { @@ -664,7 +662,7 @@ void set_init_3(void) } if (buf_is_empty(curbuf)) { - int idx_ffs = findoption_len(S_LEN("ffs")); + int idx_ffs = find_option("ffs"); // Apply the first entry of 'fileformats' to the initial buffer. if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET)) { @@ -1132,7 +1130,7 @@ const char *find_option_end(const char *arg, OptIndex *opt_idxp) p++; } - *opt_idxp = findoption_len(arg, (size_t)(p - arg)); + *opt_idxp = find_option_len(arg, (size_t)(p - arg)); return p; } @@ -3009,87 +3007,6 @@ void check_redraw(uint32_t flags) check_redraw_for(curbuf, curwin, flags); } -/// Find index for named option -/// -/// @param[in] arg Option to find index for. -/// @param[in] len Length of the option. -/// -/// @return Index of the option or kOptInvalid if option was not found. -OptIndex findoption_len(const char *const arg, const size_t len) -{ - const char *s; - static int quick_tab[27] = { 0, 0 }; // quick access table - - // For first call: Initialize the quick-access table. - // It contains the index for the first option that starts with a certain - // letter. There are 26 letters, plus the first "t_" option. - if (quick_tab[1] == 0) { - const char *p = options[0].fullname; - for (OptIndex i = 1; i < kOptIndexCount; i++) { - s = options[i].fullname; - - if (s[0] != p[0]) { - if (s[0] == 't' && s[1] == '_') { - quick_tab[26] = i; - } else { - quick_tab[CHAR_ORD_LOW(s[0])] = i; - } - } - p = s; - } - } - - // Check for name starting with an illegal character. - if (len == 0 || arg[0] < 'a' || arg[0] > 'z') { - return kOptInvalid; - } - - OptIndex opt_idx; - const bool is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_'); - if (is_term_opt) { - opt_idx = quick_tab[26]; - } else { - opt_idx = quick_tab[CHAR_ORD_LOW(arg[0])]; - } - // Match full name - for (; opt_idx < kOptIndexCount; opt_idx++) { - s = options[opt_idx].fullname; - - // Break if first character no longer matches. - if (s[0] != arg[0]) { - opt_idx = kOptIndexCount; - break; - } - - if (strncmp(arg, s, len) == 0 && s[len] == NUL) { - break; - } - } - if (opt_idx == kOptIndexCount && !is_term_opt) { - opt_idx = quick_tab[CHAR_ORD_LOW(arg[0])]; - // Match short name - for (; opt_idx < kOptIndexCount; opt_idx++) { - s = options[opt_idx].shortname; - if (s != NULL && strncmp(arg, s, len) == 0 && s[len] == NUL) { - break; - } - } - } - if (opt_idx == kOptIndexCount) { - opt_idx = kOptInvalid; - } else { - // Nvim: handle option aliases. - if (strncmp(options[opt_idx].fullname, "viminfo", 7) == 0) { - if (strlen(options[opt_idx].fullname) == 7) { - return findoption_len("shada", 5); - } - assert(strcmp(options[opt_idx].fullname, "viminfofile") == 0); - return findoption_len("shadafile", 9); - } - } - return opt_idx; -} - bool is_tty_option(const char *name) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { @@ -3147,15 +3064,28 @@ bool set_tty_option(const char *name, char *value) return false; } +/// Find index for an option. Don't go beyond `len` length. +/// +/// @param[in] name Option name. +/// @param len Option name length. +/// +/// @return Option index or kOptInvalid if option was not found. +OptIndex find_option_len(const char *const name, size_t len) + FUNC_ATTR_NONNULL_ALL +{ + int index = find_option_hash(name, len); + return index >= 0 ? option_hash_elems[index].opt_idx : kOptInvalid; +} + /// Find index for an option. /// -/// @param[in] arg Option name. +/// @param[in] name Option name. /// /// @return Option index or kOptInvalid if option was not found. -OptIndex findoption(const char *const arg) +OptIndex find_option(const char *const name) FUNC_ATTR_NONNULL_ALL { - return findoption_len(arg, strlen(arg)); + return find_option_len(name, strlen(name)); } /// Free an allocated OptVal. @@ -5229,7 +5159,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) return; } nextchar = *p; - opt_idx = findoption_len(arg, (size_t)(p - arg)); + opt_idx = find_option_len(arg, (size_t)(p - arg)); if (opt_idx == kOptInvalid || options[opt_idx].var == NULL) { xp->xp_context = EXPAND_NOTHING; return; @@ -5534,7 +5464,7 @@ int ExpandOldSetting(int *numMatches, char ***matches) // For a terminal key code expand_option_idx is kOptInvalid. if (expand_option_idx == kOptInvalid) { - expand_option_idx = findoption(expand_option_name); + expand_option_idx = find_option(expand_option_name); } if (expand_option_idx != kOptInvalid) { @@ -6146,7 +6076,7 @@ int get_sidescrolloff_value(win_T *wp) Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Error *err) { - OptIndex opt_idx = findoption_len(name.data, name.size); + OptIndex opt_idx = find_option_len(name.data, name.size); VALIDATE_S(opt_idx != kOptInvalid, "option (not found)", name.data, { return (Dictionary)ARRAY_DICT_INIT; }); diff --git a/src/nvim/option.h b/src/nvim/option.h index 034c3de148..44cba70302 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -134,7 +134,7 @@ static inline bool option_has_type(OptIndex opt_idx, OptValType type) // Ensure that the type is valid before accessing type_flags. assert(type > kOptValTypeNil && type < kOptValTypeSize); // Bitshift 1 by the value of type to get the type's corresponding flag, and check if it's set in - // the type_flags bit_field. + // the type_flags bit field. return get_option(opt_idx)->type_flags & (1 << type); } diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 6d61a6d64e..0d5c24a793 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2,6 +2,7 @@ --- @field full_name string --- @field desc? string --- @field abbreviation? string +--- @field alias? string|string[] --- @field short_desc? string|fun(): string --- @field varname? string --- @field pv_name? string @@ -84,6 +85,7 @@ end return { cstr = cstr, --- @type vim.option_meta[] + --- The order of the options MUST be alphabetic for ":set all". options = { { abbreviation = 'al', @@ -6809,6 +6811,7 @@ return { }, { abbreviation = 'sd', + alias = { 'vi', 'viminfo' }, cb = 'did_set_shada', defaults = { if_true = "!,'100,<50,s10,h", @@ -6940,6 +6943,7 @@ return { }, { abbreviation = 'sdf', + alias = { 'vif', 'viminfofile' }, defaults = { if_true = '' }, deny_duplicates = true, desc = [=[ @@ -9374,22 +9378,6 @@ return { type = 'string', varname = 'p_vop', }, - { - abbreviation = 'vi', - full_name = 'viminfo', - nodefault = true, - scope = { 'global' }, - short_desc = N_('Alias for shada'), - type = 'string', - }, - { - abbreviation = 'vif', - full_name = 'viminfofile', - nodefault = true, - scope = { 'global' }, - short_desc = N_('Alias for shadafile instead'), - type = 'string', - }, { abbreviation = 've', cb = 'did_set_virtualedit', diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index c7d9a65b86..f4ffa2a6b8 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1545,7 +1545,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op break; case STL_SHOWCMD: - if (p_sc && (opt_idx == kOptInvalid || findoption(p_sloc) == opt_idx)) { + if (p_sc && (opt_idx == kOptInvalid || find_option(p_sloc) == opt_idx)) { str = showcmd_buf; } break; -- cgit From 69bc519b53ebf78fd95c8256468e7d538ebcb948 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 12 Dec 2023 15:40:21 +0100 Subject: refactor: move non-symbols to defs.h headers --- src/clint.py | 13 ++-- src/nvim/api/options.c | 1 - src/nvim/api/private/dispatch.h | 2 +- src/nvim/api/private/helpers.c | 1 - src/nvim/api/private/helpers.h | 8 +- src/nvim/api/ui.c | 2 +- src/nvim/api/vim.c | 1 + src/nvim/arglist.c | 1 - src/nvim/arglist.h | 2 - src/nvim/autocmd.c | 2 +- src/nvim/buffer.c | 1 - src/nvim/bufwrite.c | 1 + src/nvim/channel.c | 3 + src/nvim/channel.h | 55 +------------ src/nvim/channel_defs.h | 74 ++++++++++++++++++ src/nvim/decoration.c | 2 +- src/nvim/drawscreen.c | 1 + src/nvim/eval.c | 1 + src/nvim/eval/funcs.c | 1 + src/nvim/eval/gc.h | 2 +- src/nvim/event/defs.h | 166 ++++++++++++++++++++++++++++++++++++++++ src/nvim/event/libuv_process.c | 2 +- src/nvim/event/loop.c | 1 + src/nvim/event/loop.h | 39 ---------- src/nvim/event/multiqueue.h | 13 +--- src/nvim/event/process.c | 2 + src/nvim/event/rstream.c | 1 + src/nvim/event/signal.c | 1 + src/nvim/event/signal.h | 15 +--- src/nvim/event/socket.c | 1 + src/nvim/event/socket.h | 29 +------ src/nvim/event/stream.c | 1 + src/nvim/event/stream.h | 50 +----------- src/nvim/event/time.c | 3 + src/nvim/event/time.h | 14 +--- src/nvim/event/wstream.c | 2 + src/nvim/event/wstream.h | 12 +-- src/nvim/ex_cmds.c | 1 - src/nvim/ex_cmds.h | 29 ------- src/nvim/ex_cmds_defs.h | 25 ++++++ src/nvim/ex_docmd.c | 2 +- src/nvim/extmark.h | 3 +- src/nvim/input.c | 2 +- src/nvim/log.h | 36 +-------- src/nvim/log_defs.h | 36 +++++++++ src/nvim/lua/executor.c | 1 - src/nvim/mark.c | 5 +- src/nvim/mark.h | 87 +-------------------- src/nvim/mark_defs.h | 76 ++++++++++++++++++ src/nvim/mbyte.h | 2 +- src/nvim/message.c | 2 + src/nvim/message.h | 54 +------------ src/nvim/message_defs.h | 59 ++++++++++++++ src/nvim/msgpack_rpc/channel.c | 3 +- src/nvim/msgpack_rpc/channel.h | 6 +- src/nvim/msgpack_rpc/server.c | 1 + src/nvim/option.c | 1 - src/nvim/option_defs.h | 3 +- src/nvim/os/input.c | 1 + src/nvim/os/pty_process_unix.c | 2 +- src/nvim/os/shell.c | 2 + src/nvim/os/signal.c | 1 + src/nvim/os/time.c | 2 +- src/nvim/os/tty.h | 2 +- src/nvim/popupmenu.h | 2 +- src/nvim/spell.c | 1 + src/nvim/spellsuggest.c | 1 + src/nvim/statusline.h | 2 +- src/nvim/tag.c | 1 + src/nvim/terminal.c | 1 + src/nvim/terminal.h | 1 + src/nvim/tui/input.c | 1 + src/nvim/tui/tui.c | 1 + src/nvim/ui.c | 1 + src/nvim/ui_client.c | 2 +- src/nvim/vim_defs.h | 1 - src/nvim/window.c | 1 + 77 files changed, 513 insertions(+), 473 deletions(-) create mode 100644 src/nvim/channel_defs.h create mode 100644 src/nvim/log_defs.h create mode 100644 src/nvim/message_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 021d6b0a16..537406cd24 100755 --- a/src/clint.py +++ b/src/clint.py @@ -900,12 +900,12 @@ def CheckIncludes(filename, lines, error): # These should be synced with the ignored headers in the `iwyu` target in # the Makefile. check_includes_ignore = [ - "src/nvim/api/private/helpers.h", "src/nvim/api/private/validate.h", "src/nvim/assert_defs.h", "src/nvim/buffer.h", "src/nvim/buffer_defs.h", "src/nvim/channel.h", + "src/nvim/channel_defs.h", "src/nvim/charset.h", "src/nvim/drawline.h", "src/nvim/eval.h", @@ -916,7 +916,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/eval/window.h", "src/nvim/event/libuv_process.h", "src/nvim/event/loop.h", - "src/nvim/event/multiqueue.h", "src/nvim/event/process.h", "src/nvim/event/rstream.h", "src/nvim/event/signal.h", @@ -932,8 +931,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/keycodes.h", "src/nvim/lua/executor.h", "src/nvim/main.h", - "src/nvim/mark.h", - "src/nvim/msgpack_rpc/channel.h", "src/nvim/msgpack_rpc/channel_defs.h", "src/nvim/msgpack_rpc/helpers.h", "src/nvim/msgpack_rpc/unpacker.h", @@ -949,10 +946,12 @@ def CheckIncludes(filename, lines, error): ] skip_headers = [ - "klib/kvec.h", - "klib/klist.h", "auto/config.h", - "nvim/func_attr.h" + "klib/klist.h", + "klib/kvec.h", + "nvim/func_attr.h", + "nvim/gettext.h", + "nvim/globals.h" ] for i in check_includes_ignore: diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index a3ea7d9d47..ea617dffaf 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -15,7 +15,6 @@ #include "nvim/macros_defs.h" #include "nvim/memory.h" #include "nvim/option.h" -#include "nvim/option_vars.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index 88f846f813..b627db6b00 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -27,5 +27,5 @@ extern const MsgpackRpcRequestHandler method_handlers[]; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/dispatch.h.generated.h" # include "api/private/dispatch_wrappers.h.generated.h" // IWYU pragma: export -# include "keysets_defs.generated.h" +# include "keysets_defs.generated.h" // IWYU pragma: export #endif diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 2772fa8b59..70e63d0ad5 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -17,7 +17,6 @@ #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/eval/vars.h" #include "nvim/ex_eval.h" #include "nvim/garray.h" diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index e61dd5f992..64558f0410 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -2,21 +2,15 @@ #include #include -#include #include "klib/kvec.h" #include "nvim/api/private/defs.h" -#include "nvim/api/private/dispatch.h" -#include "nvim/decoration.h" -#include "nvim/eval/typval_defs.h" #include "nvim/ex_eval_defs.h" -#include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/map_defs.h" -#include "nvim/memory.h" -#include "nvim/message.h" +#include "nvim/message_defs.h" // IWYU pragma: keep #define OBJECT_OBJ(o) o diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index b73c026d57..678d23fbeb 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -15,7 +15,7 @@ #include "nvim/autocmd.h" #include "nvim/channel.h" #include "nvim/eval.h" -#include "nvim/event/loop.h" +#include "nvim/event/defs.h" #include "nvim/event/wstream.h" #include "nvim/globals.h" #include "nvim/grid.h" diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 91f908bb88..70e6b840de 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -54,6 +54,7 @@ #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/input.h" +#include "nvim/os/os_defs.h" #include "nvim/os/process.h" #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index 064543b430..8bc8edb572 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -13,7 +13,6 @@ #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/eval/window.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" diff --git a/src/nvim/arglist.h b/src/nvim/arglist.h index 97729f466c..d117f6163b 100644 --- a/src/nvim/arglist.h +++ b/src/nvim/arglist.h @@ -2,9 +2,7 @@ #include "nvim/arglist_defs.h" // IWYU pragma: export #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep -#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep -#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "arglist.h.generated.h" diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 72b0852d8d..bfcf566fe3 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -19,7 +19,7 @@ #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" -#include "nvim/event/multiqueue.h" +#include "nvim/event/defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fileio.h" diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0392ff6ebd..75c6545c1d 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -39,7 +39,6 @@ #include "nvim/charset.h" #include "nvim/cmdexpand.h" #include "nvim/cursor.h" -#include "nvim/decoration.h" #include "nvim/diff.h" #include "nvim/digraph.h" #include "nvim/drawscreen.h" diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index 06bd05b11d..f8df273375 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -37,6 +37,7 @@ #include "nvim/option_vars.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/sha256.h" diff --git a/src/nvim/channel.c b/src/nvim/channel.c index fb4711f7d9..42935933e0 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -15,8 +15,10 @@ #include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/eval/typval.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" #include "nvim/event/socket.h" +#include "nvim/event/stream.h" #include "nvim/event/wstream.h" #include "nvim/garray.h" #include "nvim/gettext.h" @@ -32,6 +34,7 @@ #include "nvim/os/shell.h" #include "nvim/path.h" #include "nvim/rbuffer.h" +#include "nvim/types_defs.h" #ifdef MSWIN # include "nvim/os/fs.h" diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 6deea08c83..2b6356b216 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -4,6 +4,7 @@ #include #include +#include "nvim/channel_defs.h" // IWYU pragma: export #include "nvim/eval/typval_defs.h" #include "nvim/event/libuv_process.h" #include "nvim/event/multiqueue.h" @@ -19,60 +20,6 @@ #include "nvim/terminal.h" #include "nvim/types_defs.h" -#define CHAN_STDIO 1 -#define CHAN_STDERR 2 - -typedef enum { - kChannelStreamProc, - kChannelStreamSocket, - kChannelStreamStdio, - kChannelStreamStderr, - kChannelStreamInternal, -} ChannelStreamType; - -typedef enum { - kChannelPartStdin, - kChannelPartStdout, - kChannelPartStderr, - kChannelPartRpc, - kChannelPartAll, -} ChannelPart; - -typedef enum { - kChannelStdinPipe, - kChannelStdinNull, -} ChannelStdinMode; - -typedef struct { - Stream in; - Stream out; -} StdioPair; - -typedef struct { - bool closed; -} StderrState; - -typedef struct { - LuaRef cb; - bool closed; -} InternalState; - -typedef struct { - Callback cb; - dict_T *self; - garray_T buffer; - bool eof; - bool buffered; - bool fwd_err; - const char *type; -} CallbackReader; - -#define CALLBACK_READER_INIT ((CallbackReader){ .cb = CALLBACK_NONE, \ - .self = NULL, \ - .buffer = GA_EMPTY_INIT_VALUE, \ - .buffered = false, \ - .fwd_err = false, \ - .type = NULL }) static inline bool callback_reader_set(CallbackReader reader) { return reader.cb.type != kCallbackNone || reader.self; diff --git a/src/nvim/channel_defs.h b/src/nvim/channel_defs.h new file mode 100644 index 0000000000..1af4c2de59 --- /dev/null +++ b/src/nvim/channel_defs.h @@ -0,0 +1,74 @@ +#pragma once +#include +#include +#include + +#include "nvim/eval/typval_defs.h" +#include "nvim/event/libuv_process.h" +#include "nvim/event/multiqueue.h" +#include "nvim/event/process.h" +#include "nvim/event/socket.h" +#include "nvim/event/stream.h" +#include "nvim/garray_defs.h" +#include "nvim/macros_defs.h" +#include "nvim/main.h" +#include "nvim/map_defs.h" +#include "nvim/msgpack_rpc/channel_defs.h" +#include "nvim/os/pty_process.h" +#include "nvim/terminal.h" +#include "nvim/types_defs.h" + +#define CHAN_STDIO 1 +#define CHAN_STDERR 2 + +typedef enum { + kChannelStreamProc, + kChannelStreamSocket, + kChannelStreamStdio, + kChannelStreamStderr, + kChannelStreamInternal, +} ChannelStreamType; + +typedef enum { + kChannelPartStdin, + kChannelPartStdout, + kChannelPartStderr, + kChannelPartRpc, + kChannelPartAll, +} ChannelPart; + +typedef enum { + kChannelStdinPipe, + kChannelStdinNull, +} ChannelStdinMode; + +typedef struct { + Stream in; + Stream out; +} StdioPair; + +typedef struct { + bool closed; +} StderrState; + +typedef struct { + LuaRef cb; + bool closed; +} InternalState; + +typedef struct { + Callback cb; + dict_T *self; + garray_T buffer; + bool eof; + bool buffered; + bool fwd_err; + const char *type; +} CallbackReader; + +#define CALLBACK_READER_INIT ((CallbackReader){ .cb = CALLBACK_NONE, \ + .self = NULL, \ + .buffer = GA_EMPTY_INIT_VALUE, \ + .buffered = false, \ + .fwd_err = false, \ + .type = NULL }) diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 74056b7c26..b3fad78f84 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -6,7 +6,6 @@ #include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" -#include "nvim/buffer.h" #include "nvim/decoration.h" #include "nvim/drawscreen.h" #include "nvim/extmark.h" @@ -14,6 +13,7 @@ #include "nvim/grid.h" #include "nvim/highlight.h" #include "nvim/highlight_group.h" +#include "nvim/map_defs.h" #include "nvim/marktree.h" #include "nvim/memory.h" #include "nvim/move.h" diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 314764d117..09a0a43e2f 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -91,6 +91,7 @@ #include "nvim/normal.h" #include "nvim/option.h" #include "nvim/option_vars.h" +#include "nvim/os/os_defs.h" #include "nvim/plines.h" #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 11c6034cc8..d8134c2360 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -32,6 +32,7 @@ #include "nvim/eval/vars.h" #include "nvim/event/multiqueue.h" #include "nvim/event/process.h" +#include "nvim/event/time.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 1468c5564e..ea68c010d6 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -48,6 +48,7 @@ #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/eval/window.h" +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/process.h" diff --git a/src/nvim/eval/gc.h b/src/nvim/eval/gc.h index 36149ec060..ea91952fff 100644 --- a/src/nvim/eval/gc.h +++ b/src/nvim/eval/gc.h @@ -6,5 +6,5 @@ extern dict_T *gc_first_dict; extern list_T *gc_first_list; #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "eval/gc.h.generated.h" // IWYU pragma: export +# include "eval/gc.h.generated.h" #endif diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index 56e00171e2..ffea388b9b 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -2,6 +2,10 @@ #include #include +#include +#include + +#include "nvim/rbuffer_defs.h" enum { EVENT_HANDLER_MAX_ARGC = 10, }; @@ -12,3 +16,165 @@ typedef struct { } Event; #define event_create(cb, ...) ((Event){ .handler = cb, .argv = { __VA_ARGS__ } }) + +typedef struct multiqueue MultiQueue; +typedef void (*PutCallback)(MultiQueue *multiq, void *data); + +#define multiqueue_put(q, h, ...) \ + do { \ + multiqueue_put_event(q, event_create(h, __VA_ARGS__)); \ + } while (0) + +#define CREATE_EVENT(multiqueue, handler, ...) \ + do { \ + if (multiqueue) { \ + multiqueue_put((multiqueue), (handler), __VA_ARGS__); \ + } else { \ + void *argv[] = { __VA_ARGS__ }; \ + (handler)(argv); \ + } \ + } while (0) + +// Poll for events until a condition or timeout +#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \ + do { \ + int64_t remaining = timeout; \ + uint64_t before = (remaining > 0) ? os_hrtime() : 0; \ + while (!(condition)) { \ + LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \ + if (remaining == 0) { \ + break; \ + } else if (remaining > 0) { \ + uint64_t now = os_hrtime(); \ + remaining -= (int64_t)((now - before) / 1000000); \ + before = now; \ + if (remaining <= 0) { \ + break; \ + } \ + } \ + } \ + } while (0) + +#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \ + do { \ + if (multiqueue && !multiqueue_empty(multiqueue)) { \ + multiqueue_process_events(multiqueue); \ + } else { \ + loop_poll_events(loop, timeout); \ + } \ + } while (0) + +struct signal_watcher; + +typedef struct signal_watcher SignalWatcher; +typedef void (*signal_cb)(SignalWatcher *watcher, int signum, void *data); +typedef void (*signal_close_cb)(SignalWatcher *watcher, void *data); + +struct signal_watcher { + uv_signal_t uv; + void *data; + signal_cb cb; + signal_close_cb close_cb; + MultiQueue *events; +}; + +struct time_watcher; + +typedef struct time_watcher TimeWatcher; +typedef void (*time_cb)(TimeWatcher *watcher, void *data); + +struct time_watcher { + uv_timer_t uv; + void *data; + time_cb cb, close_cb; + MultiQueue *events; + bool blockable; +}; + +struct wbuffer; + +typedef struct wbuffer WBuffer; +typedef void (*wbuffer_data_finalizer)(void *data); + +struct wbuffer { + size_t size, refcount; + char *data; + wbuffer_data_finalizer cb; +}; + +struct stream; + +typedef struct stream Stream; +/// Type of function called when the Stream buffer is filled with data +/// +/// @param stream The Stream instance +/// @param buf The associated RBuffer instance +/// @param count Number of bytes that was read. +/// @param data User-defined data +/// @param eof If the stream reached EOF. +typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof); + +/// Type of function called when the Stream has information about a write +/// request. +/// +/// @param stream The Stream instance +/// @param data User-defined data +/// @param status 0 on success, anything else indicates failure +typedef void (*stream_write_cb)(Stream *stream, void *data, int status); +typedef void (*stream_close_cb)(Stream *stream, void *data); + +struct stream { + bool closed; + bool did_eof; + union { + uv_pipe_t pipe; + uv_tcp_t tcp; + uv_idle_t idle; +#ifdef MSWIN + uv_tty_t tty; +#endif + } uv; + uv_stream_t *uvstream; + uv_buf_t uvbuf; + RBuffer *buffer; + uv_file fd; + stream_read_cb read_cb; + stream_write_cb write_cb; + void *cb_data; + stream_close_cb close_cb, internal_close_cb; + void *close_cb_data, *internal_data; + size_t fpos; + size_t curmem; + size_t maxmem; + size_t pending_reqs; + size_t num_bytes; + MultiQueue *events; +}; + +struct socket_watcher; + +#define ADDRESS_MAX_SIZE 256 + +typedef struct socket_watcher SocketWatcher; +typedef void (*socket_cb)(SocketWatcher *watcher, int result, void *data); +typedef void (*socket_close_cb)(SocketWatcher *watcher, void *data); + +struct socket_watcher { + // Pipe/socket path, or TCP address string + char addr[ADDRESS_MAX_SIZE]; + // TCP server or unix socket (named pipe on Windows) + union { + struct { + uv_tcp_t handle; + struct addrinfo *addrinfo; + } tcp; + struct { + uv_pipe_t handle; + } pipe; + } uv; + uv_stream_t *stream; + void *data; + socket_cb cb; + socket_close_cb close_cb; + MultiQueue *events; +}; diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 8264adb1fc..07c059423a 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -4,9 +4,9 @@ #include #include "nvim/eval/typval.h" +#include "nvim/event/defs.h" #include "nvim/event/libuv_process.h" #include "nvim/event/process.h" -#include "nvim/event/stream.h" #include "nvim/log.h" #include "nvim/os/os.h" #include "nvim/ui_client.h" diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 697bdb7aa8..a2cb72771c 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -5,6 +5,7 @@ #include "nvim/event/defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/log.h" #include "nvim/memory.h" #include "nvim/os/time.h" diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index 442a159631..b567df5456 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -44,45 +44,6 @@ typedef struct loop { bool closing; ///< Set to true if loop_close() has been called } Loop; -#define CREATE_EVENT(multiqueue, handler, ...) \ - do { \ - if (multiqueue) { \ - multiqueue_put((multiqueue), (handler), __VA_ARGS__); \ - } else { \ - void *argv[] = { __VA_ARGS__ }; \ - (handler)(argv); \ - } \ - } while (0) - -// Poll for events until a condition or timeout -#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \ - do { \ - int64_t remaining = timeout; \ - uint64_t before = (remaining > 0) ? os_hrtime() : 0; \ - while (!(condition)) { \ - LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \ - if (remaining == 0) { \ - break; \ - } else if (remaining > 0) { \ - uint64_t now = os_hrtime(); \ - remaining -= (int64_t)((now - before) / 1000000); \ - before = now; \ - if (remaining <= 0) { \ - break; \ - } \ - } \ - } \ - } while (0) - -#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \ - do { \ - if (multiqueue && !multiqueue_empty(multiqueue)) { \ - multiqueue_process_events(multiqueue); \ - } else { \ - loop_poll_events(loop, timeout); \ - } \ - } while (0) - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/loop.h.generated.h" #endif diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index 7de307f77e..26e3bc1c30 100644 --- a/src/nvim/event/multiqueue.h +++ b/src/nvim/event/multiqueue.h @@ -1,17 +1,8 @@ #pragma once -#include +#include // IWYU pragma: keep -#include "nvim/event/defs.h" -#include "nvim/lib/queue.h" - -typedef struct multiqueue MultiQueue; -typedef void (*PutCallback)(MultiQueue *multiq, void *data); - -#define multiqueue_put(q, h, ...) \ - do { \ - multiqueue_put_event(q, event_create(h, __VA_ARGS__)); \ - } while (0) +#include "nvim/event/defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.h.generated.h" diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index ac9c4973ce..3d9578936c 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -6,7 +6,9 @@ #include "klib/klist.h" #include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/process.h" +#include "nvim/event/stream.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/main.h" diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 130c080db5..df97b592e4 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -5,6 +5,7 @@ #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/event/stream.h" diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index 2d6cccf53a..3a100812cf 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -1,6 +1,7 @@ #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/signal.h" diff --git a/src/nvim/event/signal.h b/src/nvim/event/signal.h index 946de1b4f0..711797ca71 100644 --- a/src/nvim/event/signal.h +++ b/src/nvim/event/signal.h @@ -2,23 +2,10 @@ #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" -struct signal_watcher; - -typedef struct signal_watcher SignalWatcher; -typedef void (*signal_cb)(SignalWatcher *watcher, int signum, void *data); -typedef void (*signal_close_cb)(SignalWatcher *watcher, void *data); - -struct signal_watcher { - uv_signal_t uv; - void *data; - signal_cb cb; - signal_close_cb close_cb; - MultiQueue *events; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/signal.h.generated.h" #endif diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index cde53a00e1..3c7b98bfe7 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -7,6 +7,7 @@ #include "nvim/ascii_defs.h" #include "nvim/charset.h" +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/socket.h" #include "nvim/event/stream.h" diff --git a/src/nvim/event/socket.h b/src/nvim/event/socket.h index 504af3c7a8..24ba361efa 100644 --- a/src/nvim/event/socket.h +++ b/src/nvim/event/socket.h @@ -2,39 +2,12 @@ #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -struct socket_watcher; - -#define ADDRESS_MAX_SIZE 256 - -typedef struct socket_watcher SocketWatcher; -typedef void (*socket_cb)(SocketWatcher *watcher, int result, void *data); -typedef void (*socket_close_cb)(SocketWatcher *watcher, void *data); - -struct socket_watcher { - // Pipe/socket path, or TCP address string - char addr[ADDRESS_MAX_SIZE]; - // TCP server or unix socket (named pipe on Windows) - union { - struct { - uv_tcp_t handle; - struct addrinfo *addrinfo; - } tcp; - struct { - uv_pipe_t handle; - } pipe; - } uv; - uv_stream_t *stream; - void *data; - socket_cb cb; - socket_close_cb close_cb; - MultiQueue *events; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/socket.h.generated.h" #endif diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 8baecbbb31..886e93931b 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -4,6 +4,7 @@ #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/log.h" diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index ab694e2247..588aab12b0 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -4,59 +4,11 @@ #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/rbuffer_defs.h" -struct stream; - -typedef struct stream Stream; -/// Type of function called when the Stream buffer is filled with data -/// -/// @param stream The Stream instance -/// @param buf The associated RBuffer instance -/// @param count Number of bytes that was read. -/// @param data User-defined data -/// @param eof If the stream reached EOF. -typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof); - -/// Type of function called when the Stream has information about a write -/// request. -/// -/// @param stream The Stream instance -/// @param data User-defined data -/// @param status 0 on success, anything else indicates failure -typedef void (*stream_write_cb)(Stream *stream, void *data, int status); -typedef void (*stream_close_cb)(Stream *stream, void *data); - -struct stream { - bool closed; - bool did_eof; - union { - uv_pipe_t pipe; - uv_tcp_t tcp; - uv_idle_t idle; -#ifdef MSWIN - uv_tty_t tty; -#endif - } uv; - uv_stream_t *uvstream; - uv_buf_t uvbuf; - RBuffer *buffer; - uv_file fd; - stream_read_cb read_cb; - stream_write_cb write_cb; - void *cb_data; - stream_close_cb close_cb, internal_close_cb; - void *close_cb_data, *internal_data; - size_t fpos; - size_t curmem; - size_t maxmem; - size_t pending_reqs; - size_t num_bytes; - MultiQueue *events; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/stream.h.generated.h" #endif diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index 7206d74176..de837fd278 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -1,7 +1,10 @@ +#include #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/time.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/event/time.h b/src/nvim/event/time.h index 3514566901..85171f315a 100644 --- a/src/nvim/event/time.h +++ b/src/nvim/event/time.h @@ -3,22 +3,10 @@ #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" -struct time_watcher; - -typedef struct time_watcher TimeWatcher; -typedef void (*time_cb)(TimeWatcher *watcher, void *data); - -struct time_watcher { - uv_timer_t uv; - void *data; - time_cb cb, close_cb; - MultiQueue *events; - bool blockable; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/time.h.generated.h" #endif diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index 239f64c013..70cc5b6547 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -1,7 +1,9 @@ #include #include +#include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/event/wstream.h" diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h index 4cba7bde8f..d61ab644f4 100644 --- a/src/nvim/event/wstream.h +++ b/src/nvim/event/wstream.h @@ -5,20 +5,10 @@ #include #include +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/stream.h" -struct wbuffer; - -typedef struct wbuffer WBuffer; -typedef void (*wbuffer_data_finalizer)(void *data); - -struct wbuffer { - size_t size, refcount; - char *data; - wbuffer_data_finalizer cb; -}; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/wstream.h.generated.h" #endif diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 786612070e..96429c96f7 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -19,7 +19,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" #include "nvim/bufwrite.h" #include "nvim/change.h" diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 011d42c6d9..2f576731f4 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -1,35 +1,6 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep -#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: export -#include "nvim/os/time_defs.h" -#include "nvim/pos_defs.h" // IWYU pragma: keep - -/// flags for do_ecmd() -enum { - ECMD_HIDE = 0x01, ///< don't free the current buffer - ECMD_SET_HELP = 0x02, ///< set b_help flag of (new) buffer before opening file - ECMD_OLDBUF = 0x04, ///< use existing buffer if it exists - ECMD_FORCEIT = 0x08, ///< ! used in Ex command - ECMD_ADDBUF = 0x10, ///< don't edit, just add to buffer list - ECMD_ALTBUF = 0x20, ///< like ECMD_ADDBUF and set the alternate file - ECMD_NOWINENTER = 0x40, ///< do not trigger BufWinEnter -}; - -/// for lnum argument in do_ecmd() -enum { - ECMD_LASTL = 0, ///< use last position in loaded file - ECMD_LAST = -1, ///< use last position in all files - ECMD_ONE = 1, ///< use first line -}; - -/// Previous :substitute replacement string definition -typedef struct { - char *sub; ///< Previous replacement string. - Timestamp timestamp; ///< Time when it was last set. - list_T *additional_elements; ///< Additional data left from ShaDa file. -} SubReplacementString; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_cmds.h.generated.h" diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 00363884ec..5ece6db8e9 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -229,3 +229,28 @@ typedef struct { bool bar; } magic; } CmdParseInfo; + +/// flags for do_ecmd() +enum { + ECMD_HIDE = 0x01, ///< don't free the current buffer + ECMD_SET_HELP = 0x02, ///< set b_help flag of (new) buffer before opening file + ECMD_OLDBUF = 0x04, ///< use existing buffer if it exists + ECMD_FORCEIT = 0x08, ///< ! used in Ex command + ECMD_ADDBUF = 0x10, ///< don't edit, just add to buffer list + ECMD_ALTBUF = 0x20, ///< like ECMD_ADDBUF and set the alternate file + ECMD_NOWINENTER = 0x40, ///< do not trigger BufWinEnter +}; + +/// for lnum argument in do_ecmd() +enum { + ECMD_LASTL = 0, ///< use last position in loaded file + ECMD_LAST = -1, ///< use last position in all files + ECMD_ONE = 1, ///< use first line +}; + +/// Previous :substitute replacement string definition +typedef struct { + char *sub; ///< Previous replacement string. + Timestamp timestamp; ///< Time when it was last set. + list_T *additional_elements; ///< Additional data left from ShaDa file. +} SubReplacementString; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index ff80ee9e54..d8e2c54efa 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -29,7 +29,7 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" -#include "nvim/event/loop.h" +#include "nvim/event/defs.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index 5ba079bd12..e83c8d1257 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -5,10 +5,9 @@ #include "klib/kvec.h" #include "nvim/buffer_defs.h" // IWYU pragma: keep -#include "nvim/decoration_defs.h" // IWYU pragma: keep #include "nvim/extmark_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" -#include "nvim/marktree_defs.h" // IWYU pragma: keep +#include "nvim/marktree_defs.h" #include "nvim/pos_defs.h" EXTERN int curbuf_splice_pending INIT( = 0); diff --git a/src/nvim/input.c b/src/nvim/input.c index fb25968071..a2a9692cb4 100644 --- a/src/nvim/input.c +++ b/src/nvim/input.c @@ -7,7 +7,7 @@ #include #include "nvim/ascii_defs.h" -#include "nvim/event/multiqueue.h" +#include "nvim/event/defs.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/log.h b/src/nvim/log.h index b277e09a0f..0a9a86c905 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -1,50 +1,18 @@ #pragma once -#include -#include - -#include "auto/config.h" +#include "nvim/log_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" // USDT probes. Example invocation: // NVIM_PROBE(nvim_foo_bar, 1, string.data); #if defined(HAVE_SYS_SDT_H) -# include // NOLINT +# include // IWYU pragma: keep # define NVIM_PROBE(name, n, ...) STAP_PROBE##n(neovim, name, __VA_ARGS__) #else # define NVIM_PROBE(name, n, ...) #endif -#define LOGLVL_DBG 1 -#define LOGLVL_INF 2 -#define LOGLVL_WRN 3 -#define LOGLVL_ERR 4 - -#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, __VA_ARGS__) - -#ifdef NVIM_LOG_DEBUG -# define DLOG(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, true, __VA_ARGS__) -# define DLOGN(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, false, __VA_ARGS__) -# define ILOG(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, true, __VA_ARGS__) -# define ILOGN(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, false, __VA_ARGS__) -#else -# define DLOG(...) -# define DLOGN(...) -# define ILOG(...) -# define ILOGN(...) -#endif - -#define WLOG(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, true, __VA_ARGS__) -#define WLOGN(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, false, __VA_ARGS__) -#define ELOG(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, true, __VA_ARGS__) -#define ELOGN(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, false, __VA_ARGS__) - -#ifdef HAVE_EXECINFO_BACKTRACE -# define LOG_CALLSTACK() log_callstack(__func__, __LINE__) -# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) -#endif - // uncrustify:off #if NVIM_HAS_INCLUDE() # include // IWYU pragma: keep diff --git a/src/nvim/log_defs.h b/src/nvim/log_defs.h new file mode 100644 index 0000000000..1b666720fc --- /dev/null +++ b/src/nvim/log_defs.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "auto/config.h" +#include "nvim/macros_defs.h" + +#define LOGLVL_DBG 1 +#define LOGLVL_INF 2 +#define LOGLVL_WRN 3 +#define LOGLVL_ERR 4 + +#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, __VA_ARGS__) + +#ifdef NVIM_LOG_DEBUG +# define DLOG(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, true, __VA_ARGS__) +# define DLOGN(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, false, __VA_ARGS__) +# define ILOG(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, true, __VA_ARGS__) +# define ILOGN(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, false, __VA_ARGS__) +#else +# define DLOG(...) +# define DLOGN(...) +# define ILOG(...) +# define ILOGN(...) +#endif + +#define WLOG(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, true, __VA_ARGS__) +#define WLOGN(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, false, __VA_ARGS__) +#define ELOG(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, true, __VA_ARGS__) +#define ELOGN(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, false, __VA_ARGS__) + +#ifdef HAVE_EXECINFO_BACKTRACE +# define LOG_CALLSTACK() log_callstack(__func__, __LINE__) +# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) +#endif diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 0763bbd329..77c3f22da8 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -27,7 +27,6 @@ #include "nvim/eval/userfunc.h" #include "nvim/event/defs.h" #include "nvim/event/loop.h" -#include "nvim/event/multiqueue.h" #include "nvim/event/time.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 1e2462970f..54b1df99a2 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -2,13 +2,13 @@ #include #include +#include #include #include #include #include "nvim/ascii_defs.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/diff.h" @@ -16,7 +16,6 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" #include "nvim/extmark.h" -#include "nvim/extmark_defs.h" #include "nvim/fold.h" #include "nvim/gettext.h" #include "nvim/globals.h" @@ -32,7 +31,9 @@ #include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/path.h" +#include "nvim/pos_defs.h" #include "nvim/quickfix.h" #include "nvim/strings.h" #include "nvim/textobject.h" diff --git a/src/nvim/mark.h b/src/nvim/mark.h index 990be69028..b1a093bee0 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -1,54 +1,10 @@ #pragma once -#include -#include - #include "nvim/ascii_defs.h" -#include "nvim/buffer_defs.h" -#include "nvim/ex_cmds_defs.h" -#include "nvim/extmark_defs.h" +#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/mark_defs.h" // IWYU pragma: export -#include "nvim/memory.h" -#include "nvim/os/time.h" -#include "nvim/pos_defs.h" - -/// Set fmark using given value -#define SET_FMARK(fmarkp_, mark_, fnum_, view_) \ - do { \ - fmark_T *const fmarkp__ = fmarkp_; \ - fmarkp__->mark = mark_; \ - fmarkp__->fnum = fnum_; \ - fmarkp__->timestamp = os_time(); \ - fmarkp__->view = view_; \ - fmarkp__->additional_data = NULL; \ - } while (0) - -/// Free and set fmark using given value -#define RESET_FMARK(fmarkp_, mark_, fnum_, view_) \ - do { \ - fmark_T *const fmarkp___ = fmarkp_; \ - free_fmark(*fmarkp___); \ - SET_FMARK(fmarkp___, mark_, fnum_, view_); \ - } while (0) - -/// Set given extended mark (regular mark + file name) -#define SET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ - do { \ - xfmark_T *const xfmarkp__ = xfmarkp_; \ - xfmarkp__->fname = fname_; \ - SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ - } while (0) - -/// Free and set given extended mark (regular mark + file name) -#define RESET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ - do { \ - xfmark_T *const xfmarkp__ = xfmarkp_; \ - free_xfmark(*xfmarkp__); \ - xfmarkp__->fname = fname_; \ - SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ - } while (0) static inline int mark_global_index(char name) REAL_FATTR_CONST; @@ -80,47 +36,6 @@ static inline int mark_local_index(const char name) : -1)))); } -static inline bool lt(pos_T a, pos_T b) - REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; -static inline bool equalpos(pos_T a, pos_T b) - REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; -static inline bool ltoreq(pos_T a, pos_T b) - REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; -static inline void clearpos(pos_T *a) - REAL_FATTR_ALWAYS_INLINE; - -/// Return true if position a is before (less than) position b. -static inline bool lt(pos_T a, pos_T b) -{ - if (a.lnum != b.lnum) { - return a.lnum < b.lnum; - } else if (a.col != b.col) { - return a.col < b.col; - } else { - return a.coladd < b.coladd; - } -} - -/// Return true if position a and b are equal. -static inline bool equalpos(pos_T a, pos_T b) -{ - return (a.lnum == b.lnum) && (a.col == b.col) && (a.coladd == b.coladd); -} - -/// Return true if position a is less than or equal to b. -static inline bool ltoreq(pos_T a, pos_T b) -{ - return lt(a, b) || equalpos(a, b); -} - -/// Clear the pos_T structure pointed to by a. -static inline void clearpos(pos_T *a) -{ - a->lnum = 0; - a->col = 0; - a->coladd = 0; -} - /// Global marks (marks with file number or name) EXTERN xfmark_T namedfm[NGLOBALMARKS] INIT( = { 0 }); diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h index 04672a5c52..a98a741363 100644 --- a/src/nvim/mark_defs.h +++ b/src/nvim/mark_defs.h @@ -84,3 +84,79 @@ typedef struct xfilemark { } xfmark_T; #define INIT_XFMARK { INIT_FMARK, NULL } + +/// Set fmark using given value +#define SET_FMARK(fmarkp_, mark_, fnum_, view_) \ + do { \ + fmark_T *const fmarkp__ = fmarkp_; \ + fmarkp__->mark = mark_; \ + fmarkp__->fnum = fnum_; \ + fmarkp__->timestamp = os_time(); \ + fmarkp__->view = view_; \ + fmarkp__->additional_data = NULL; \ + } while (0) + +/// Free and set fmark using given value +#define RESET_FMARK(fmarkp_, mark_, fnum_, view_) \ + do { \ + fmark_T *const fmarkp___ = fmarkp_; \ + free_fmark(*fmarkp___); \ + SET_FMARK(fmarkp___, mark_, fnum_, view_); \ + } while (0) + +/// Set given extended mark (regular mark + file name) +#define SET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ + do { \ + xfmark_T *const xfmarkp__ = xfmarkp_; \ + xfmarkp__->fname = fname_; \ + SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ + } while (0) + +/// Free and set given extended mark (regular mark + file name) +#define RESET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ + do { \ + xfmark_T *const xfmarkp__ = xfmarkp_; \ + free_xfmark(*xfmarkp__); \ + xfmarkp__->fname = fname_; \ + SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ + } while (0) + +static inline bool lt(pos_T a, pos_T b) + REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; +/// Return true if position a is before (less than) position b. +static inline bool lt(pos_T a, pos_T b) +{ + if (a.lnum != b.lnum) { + return a.lnum < b.lnum; + } else if (a.col != b.col) { + return a.col < b.col; + } else { + return a.coladd < b.coladd; + } +} + +static inline bool equalpos(pos_T a, pos_T b) + REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; +/// Return true if position a and b are equal. +static inline bool equalpos(pos_T a, pos_T b) +{ + return (a.lnum == b.lnum) && (a.col == b.col) && (a.coladd == b.coladd); +} + +static inline bool ltoreq(pos_T a, pos_T b) + REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; +/// Return true if position a is less than or equal to b. +static inline bool ltoreq(pos_T a, pos_T b) +{ + return lt(a, b) || equalpos(a, b); +} + +static inline void clearpos(pos_T *a) + REAL_FATTR_ALWAYS_INLINE; +/// Clear the pos_T structure pointed to by a. +static inline void clearpos(pos_T *a) +{ + a->lnum = 0; + a->col = 0; + a->coladd = 0; +} diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 49c323282d..bae60185e2 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -3,12 +3,12 @@ #include #include #include +#include // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/func_attr.h" #include "nvim/mbyte_defs.h" // IWYU pragma: export -#include "nvim/os/os_defs.h" // IWYU pragma: export #include "nvim/types_defs.h" // IWYU pragma: keep // Return byte length of character that starts with byte "b". diff --git a/src/nvim/message.c b/src/nvim/message.c index b9935d5b5d..6aaa00cee9 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -10,6 +10,8 @@ #include #include +#include "klib/kvec.h" +#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" diff --git a/src/nvim/message.h b/src/nvim/message.h index 904fb2d3ad..15a83fca2c 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -1,53 +1,12 @@ #pragma once -#include #include #include // IWYU pragma: keep -#include -#include "klib/kvec.h" -#include "nvim/api/private/defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/grid_defs.h" #include "nvim/macros_defs.h" - -/// Types of dialogs passed to do_dialog(). -enum { - VIM_GENERIC = 0, - VIM_ERROR = 1, - VIM_WARNING = 2, - VIM_INFO = 3, - VIM_QUESTION = 4, - VIM_LAST_TYPE = 4, ///< sentinel value -}; - -/// Return values for functions like vim_dialogyesno() -enum { - VIM_YES = 2, - VIM_NO = 3, - VIM_CANCEL = 4, - VIM_ALL = 5, - VIM_DISCARDALL = 6, -}; - -enum { MSG_HIST = 0x1000, }; ///< special attribute addition: Put message in history - -typedef struct { - String text; - int attr; -} HlMessageChunk; - -typedef kvec_t(HlMessageChunk) HlMessage; - -/// Message history for `:messages` -typedef struct msg_hist { - struct msg_hist *next; ///< Next message. - char *msg; ///< Message text. - const char *kind; ///< Message kind (for msg_ext) - int attr; ///< Message highlighting. - bool multiline; ///< Multiline message. - HlMessage multiattr; ///< multiattr message. -} MessageHistoryEntry; +#include "nvim/message_defs.h" // IWYU pragma: export /// First message extern MessageHistoryEntry *first_msg_hist; @@ -79,14 +38,3 @@ EXTERN int msg_listdo_overwrite INIT( = 0); #ifdef INCLUDE_GENERATED_DECLARATIONS # include "message.h.generated.h" #endif - -// Prefer using semsg(), because perror() may send the output to the wrong -// destination and mess up the screen. -#define PERROR(msg) (void)semsg("%s: %s", (msg), strerror(errno)) - -#ifndef MSWIN -/// Headless (no UI) error message handler. -# define os_errmsg(str) fprintf(stderr, "%s", (str)) -/// Headless (no UI) message handler. -# define os_msg(str) printf("%s", (str)) -#endif diff --git a/src/nvim/message_defs.h b/src/nvim/message_defs.h new file mode 100644 index 0000000000..a0237ea78f --- /dev/null +++ b/src/nvim/message_defs.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include + +#include "klib/kvec.h" +#include "nvim/api/private/defs.h" +#include "nvim/grid_defs.h" +#include "nvim/macros_defs.h" + +/// Types of dialogs passed to do_dialog(). +enum { + VIM_GENERIC = 0, + VIM_ERROR = 1, + VIM_WARNING = 2, + VIM_INFO = 3, + VIM_QUESTION = 4, + VIM_LAST_TYPE = 4, ///< sentinel value +}; + +/// Return values for functions like vim_dialogyesno() +enum { + VIM_YES = 2, + VIM_NO = 3, + VIM_CANCEL = 4, + VIM_ALL = 5, + VIM_DISCARDALL = 6, +}; + +enum { MSG_HIST = 0x1000, }; ///< special attribute addition: Put message in history + +typedef struct { + String text; + int attr; +} HlMessageChunk; + +typedef kvec_t(HlMessageChunk) HlMessage; + +/// Message history for `:messages` +typedef struct msg_hist { + struct msg_hist *next; ///< Next message. + char *msg; ///< Message text. + const char *kind; ///< Message kind (for msg_ext) + int attr; ///< Message highlighting. + bool multiline; ///< Multiline message. + HlMessage multiattr; ///< multiattr message. +} MessageHistoryEntry; + +// Prefer using semsg(), because perror() may send the output to the wrong +// destination and mess up the screen. +#define PERROR(msg) (void)semsg("%s: %s", (msg), strerror(errno)) + +#ifndef MSWIN +/// Headless (no UI) error message handler. +# define os_errmsg(str) fprintf(stderr, "%s", (str)) +/// Headless (no UI) message handler. +# define os_msg(str) printf("%s", (str)) +#endif diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 2336853609..c9139f5f93 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -15,10 +15,9 @@ #include "nvim/api/ui.h" #include "nvim/channel.h" #include "nvim/event/defs.h" -#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/process.h" #include "nvim/event/rstream.h" -#include "nvim/event/stream.h" #include "nvim/event/wstream.h" #include "nvim/globals.h" #include "nvim/log.h" diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h index 818bee8318..a33081eadc 100644 --- a/src/nvim/msgpack_rpc/channel.h +++ b/src/nvim/msgpack_rpc/channel.h @@ -3,11 +3,7 @@ #include // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep -#include "nvim/channel.h" -#include "nvim/event/multiqueue.h" -#include "nvim/event/process.h" -#include "nvim/event/socket.h" -#include "nvim/event/wstream.h" +#include "nvim/event/defs.h" #include "nvim/macros_defs.h" #include "nvim/memory_defs.h" // IWYU pragma: keep #include "nvim/msgpack_rpc/channel_defs.h" // IWYU pragma: export diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index e60c1b88a5..0cc249b2b8 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -6,6 +6,7 @@ #include "nvim/channel.h" #include "nvim/eval.h" +#include "nvim/event/defs.h" #include "nvim/event/socket.h" #include "nvim/garray.h" #include "nvim/log.h" diff --git a/src/nvim/option.c b/src/nvim/option.c index 0d0437d45f..6237b11de2 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -84,7 +84,6 @@ #include "nvim/regexp.h" #include "nvim/runtime.h" #include "nvim/search.h" -#include "nvim/sign_defs.h" #include "nvim/spell.h" #include "nvim/spellfile.h" #include "nvim/spellsuggest.h" diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 7ccf09b934..62c02989a2 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -131,6 +131,5 @@ typedef enum { } OptReqScope; #ifdef INCLUDE_GENERATED_DECLARATIONS -// Initialize the OptIndex enum. -# include "options_enum.generated.h" +# include "options_enum.generated.h" // IWYU pragma: export #endif diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 69d328754b..e096749ce3 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -8,6 +8,7 @@ #include "nvim/api/private/defs.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index d4be3086ea..4478d9d7bd 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -32,9 +32,9 @@ #include "auto/config.h" #include "klib/klist.h" #include "nvim/eval/typval.h" +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/process.h" -#include "nvim/event/stream.h" #include "nvim/log.h" #include "nvim/os/fs.h" #include "nvim/os/os_defs.h" diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index cb8066a62d..a0401f3a24 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -11,6 +11,7 @@ #include "nvim/charset.h" #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" +#include "nvim/event/defs.h" #include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" @@ -30,6 +31,7 @@ #include "nvim/message.h" #include "nvim/option_vars.h" #include "nvim/os/fs.h" +#include "nvim/os/os_defs.h" #include "nvim/os/shell.h" #include "nvim/os/signal.h" #include "nvim/os/time.h" diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 3a861b87b4..4960fa6a19 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -8,6 +8,7 @@ #include "nvim/autocmd.h" #include "nvim/eval.h" +#include "nvim/event/defs.h" #include "nvim/event/signal.h" #include "nvim/globals.h" #include "nvim/log.h" diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 7f3e44f680..f842bb0ab8 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -7,7 +7,7 @@ #include #include "auto/config.h" -#include "nvim/event/loop.h" +#include "nvim/event/defs.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/log.h" diff --git a/src/nvim/os/tty.h b/src/nvim/os/tty.h index a24d875c05..3a78573189 100644 --- a/src/nvim/os/tty.h +++ b/src/nvim/os/tty.h @@ -1,5 +1,5 @@ #pragma once #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/tty.h.generated.h" // IWYU pragma: export +# include "os/tty.h.generated.h" #endif diff --git a/src/nvim/popupmenu.h b/src/nvim/popupmenu.h index dc741d1b77..1e4a1584ea 100644 --- a/src/nvim/popupmenu.h +++ b/src/nvim/popupmenu.h @@ -2,7 +2,7 @@ #include -#include "nvim/buffer_defs.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/grid_defs.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/spell.c b/src/nvim/spell.c index d20d113d9c..c322621038 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -90,6 +90,7 @@ #include "nvim/option_vars.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/regexp.h" diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c index efd647a5c3..c4be6f2ec7 100644 --- a/src/nvim/spellsuggest.c +++ b/src/nvim/spellsuggest.c @@ -35,6 +35,7 @@ #include "nvim/option_vars.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" +#include "nvim/os/os_defs.h" #include "nvim/pos_defs.h" #include "nvim/profile.h" #include "nvim/spell.h" diff --git a/src/nvim/statusline.h b/src/nvim/statusline.h index 59a900d566..e1038ef2ca 100644 --- a/src/nvim/statusline.h +++ b/src/nvim/statusline.h @@ -4,7 +4,7 @@ #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" -#include "nvim/option_defs.h" +#include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/statusline_defs.h" // IWYU pragma: export /// Array defining what should be done when tabline is clicked diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 7fa02d2e0a..e67fa337b3 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -43,6 +43,7 @@ #include "nvim/optionstr.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" +#include "nvim/os/os_defs.h" #include "nvim/os/time.h" #include "nvim/path.h" #include "nvim/pos_defs.h" diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 3b70ee922a..c26e2a2259 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -57,6 +57,7 @@ #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/event/defs.h" #include "nvim/event/multiqueue.h" #include "nvim/event/time.h" #include "nvim/ex_docmd.h" diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h index ffa97f17b2..dd0ef3f47c 100644 --- a/src/nvim/terminal.h +++ b/src/nvim/terminal.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 6c47d1b5c7..9ba21a6afd 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -7,6 +7,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/event/defs.h" +#include "nvim/event/stream.h" #include "nvim/macros_defs.h" #include "nvim/main.h" #include "nvim/map_defs.h" diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index f084ab212b..496c192b95 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -15,6 +15,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/cursor_shape.h" +#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/signal.h" #include "nvim/event/stream.h" diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 0fc0c5bf86..1f94e4da63 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -14,6 +14,7 @@ #include "nvim/buffer.h" #include "nvim/cursor_shape.h" #include "nvim/drawscreen.h" +#include "nvim/event/multiqueue.h" #include "nvim/ex_getln.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index d744560a86..5c9eeaabdf 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -10,7 +10,7 @@ #include "nvim/channel.h" #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" -#include "nvim/event/loop.h" +#include "nvim/event/defs.h" #include "nvim/globals.h" #include "nvim/highlight.h" #include "nvim/log.h" diff --git a/src/nvim/vim_defs.h b/src/nvim/vim_defs.h index b408eb2fd7..b6cf402b02 100644 --- a/src/nvim/vim_defs.h +++ b/src/nvim/vim_defs.h @@ -56,7 +56,6 @@ typedef enum { kCdCauseAuto, ///< On 'autochdir'. } CdCause; -// bring lots of system header files #include "nvim/os/os_defs.h" // IWYU pragma: keep // return values for functions diff --git a/src/nvim/window.c b/src/nvim/window.c index 0a09d8e27d..fe9509548f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -56,6 +56,7 @@ #include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/os/fs.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/plines.h" #include "nvim/pos_defs.h" -- cgit From d82a586a9e39f1d346c1aea78167a85c586ed3f4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 18 Dec 2023 06:18:11 +0800 Subject: refactor: move some anonymous enums back to non-defs headers (#26622) It isn't really useful to put anonymous enums only used as arguments to functions calls in _defs.h headers, as they will only be used by a file that calls those functions, which requires including a non-defs header. Also move os_msg() and os_errmsg() back to message.h, as on Windows they are actual functions instead of macros. Also remove gettext.h and globals.h from private/helpers.h. --- src/clint.py | 3 --- src/nvim/api/private/helpers.h | 4 ++-- src/nvim/channel_defs.h | 9 +-------- src/nvim/ex_cmds.h | 18 +++++++++++++++++ src/nvim/ex_cmds_defs.h | 18 ----------------- src/nvim/generators/gen_api_dispatch.lua | 2 ++ src/nvim/log.h | 1 + src/nvim/message.h | 34 ++++++++++++++++++++++++++++++++ src/nvim/message_defs.h | 34 -------------------------------- src/nvim/option.h | 1 + src/nvim/os/lang.c | 1 + 11 files changed, 60 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 537406cd24..446593303b 100755 --- a/src/clint.py +++ b/src/clint.py @@ -905,7 +905,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/buffer.h", "src/nvim/buffer_defs.h", "src/nvim/channel.h", - "src/nvim/channel_defs.h", "src/nvim/charset.h", "src/nvim/drawline.h", "src/nvim/eval.h", @@ -950,8 +949,6 @@ def CheckIncludes(filename, lines, error): "klib/klist.h", "klib/kvec.h", "nvim/func_attr.h", - "nvim/gettext.h", - "nvim/globals.h" ] for i in check_includes_ignore: diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 64558f0410..701ce91257 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -5,9 +5,9 @@ #include "klib/kvec.h" #include "nvim/api/private/defs.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_eval_defs.h" -#include "nvim/gettext.h" -#include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/map_defs.h" #include "nvim/message_defs.h" // IWYU pragma: keep diff --git a/src/nvim/channel_defs.h b/src/nvim/channel_defs.h index 1af4c2de59..f6475129ff 100644 --- a/src/nvim/channel_defs.h +++ b/src/nvim/channel_defs.h @@ -4,18 +4,11 @@ #include #include "nvim/eval/typval_defs.h" -#include "nvim/event/libuv_process.h" -#include "nvim/event/multiqueue.h" -#include "nvim/event/process.h" -#include "nvim/event/socket.h" -#include "nvim/event/stream.h" +#include "nvim/event/defs.h" #include "nvim/garray_defs.h" #include "nvim/macros_defs.h" -#include "nvim/main.h" #include "nvim/map_defs.h" #include "nvim/msgpack_rpc/channel_defs.h" -#include "nvim/os/pty_process.h" -#include "nvim/terminal.h" #include "nvim/types_defs.h" #define CHAN_STDIO 1 diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 2f576731f4..c3e4a799b5 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -2,6 +2,24 @@ #include "nvim/ex_cmds_defs.h" // IWYU pragma: export +/// flags for do_ecmd() +enum { + ECMD_HIDE = 0x01, ///< don't free the current buffer + ECMD_SET_HELP = 0x02, ///< set b_help flag of (new) buffer before opening file + ECMD_OLDBUF = 0x04, ///< use existing buffer if it exists + ECMD_FORCEIT = 0x08, ///< ! used in Ex command + ECMD_ADDBUF = 0x10, ///< don't edit, just add to buffer list + ECMD_ALTBUF = 0x20, ///< like ECMD_ADDBUF and set the alternate file + ECMD_NOWINENTER = 0x40, ///< do not trigger BufWinEnter +}; + +/// for lnum argument in do_ecmd() +enum { + ECMD_LASTL = 0, ///< use last position in loaded file + ECMD_LAST = -1, ///< use last position in all files + ECMD_ONE = 1, ///< use first line +}; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_cmds.h.generated.h" #endif diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 5ece6db8e9..cf6282ad06 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -230,24 +230,6 @@ typedef struct { } magic; } CmdParseInfo; -/// flags for do_ecmd() -enum { - ECMD_HIDE = 0x01, ///< don't free the current buffer - ECMD_SET_HELP = 0x02, ///< set b_help flag of (new) buffer before opening file - ECMD_OLDBUF = 0x04, ///< use existing buffer if it exists - ECMD_FORCEIT = 0x08, ///< ! used in Ex command - ECMD_ADDBUF = 0x10, ///< don't edit, just add to buffer list - ECMD_ALTBUF = 0x20, ///< like ECMD_ADDBUF and set the alternate file - ECMD_NOWINENTER = 0x40, ///< do not trigger BufWinEnter -}; - -/// for lnum argument in do_ecmd() -enum { - ECMD_LASTL = 0, ///< use last position in loaded file - ECMD_LAST = -1, ///< use last position in all files - ECMD_ONE = 1, ///< use first line -}; - /// Previous :substitute replacement string definition typedef struct { char *sub; ///< Previous replacement string. diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 7cec118243..5928999967 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -236,6 +236,7 @@ local keysets_defs = io.open(keysets_outputf, 'wb') output:write([[ #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/globals.h" #include "nvim/log.h" #include "nvim/map_defs.h" #include "nvim/msgpack_rpc/helpers.h" @@ -662,6 +663,7 @@ output:write([[ #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/func_attr.h" +#include "nvim/globals.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/dispatch.h" diff --git a/src/nvim/log.h b/src/nvim/log.h index 0a9a86c905..c6a033c634 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -1,5 +1,6 @@ #pragma once +#include "auto/config.h" #include "nvim/log_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" diff --git a/src/nvim/message.h b/src/nvim/message.h index 15a83fca2c..63d43fe47e 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -1,13 +1,36 @@ #pragma once +#include #include #include // IWYU pragma: keep +#include #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/grid_defs.h" #include "nvim/macros_defs.h" #include "nvim/message_defs.h" // IWYU pragma: export +/// Types of dialogs passed to do_dialog(). +enum { + VIM_GENERIC = 0, + VIM_ERROR = 1, + VIM_WARNING = 2, + VIM_INFO = 3, + VIM_QUESTION = 4, + VIM_LAST_TYPE = 4, ///< sentinel value +}; + +/// Return values for functions like vim_dialogyesno() +enum { + VIM_YES = 2, + VIM_NO = 3, + VIM_CANCEL = 4, + VIM_ALL = 5, + VIM_DISCARDALL = 6, +}; + +enum { MSG_HIST = 0x1000, }; ///< special attribute addition: Put message in history + /// First message extern MessageHistoryEntry *first_msg_hist; /// Last message @@ -38,3 +61,14 @@ EXTERN int msg_listdo_overwrite INIT( = 0); #ifdef INCLUDE_GENERATED_DECLARATIONS # include "message.h.generated.h" #endif + +// Prefer using semsg(), because perror() may send the output to the wrong +// destination and mess up the screen. +#define PERROR(msg) (void)semsg("%s: %s", (msg), strerror(errno)) + +#ifndef MSWIN +/// Headless (no UI) error message handler. +# define os_errmsg(str) fprintf(stderr, "%s", (str)) +/// Headless (no UI) message handler. +# define os_msg(str) printf("%s", (str)) +#endif diff --git a/src/nvim/message_defs.h b/src/nvim/message_defs.h index a0237ea78f..67e037fc0f 100644 --- a/src/nvim/message_defs.h +++ b/src/nvim/message_defs.h @@ -1,35 +1,12 @@ #pragma once -#include #include -#include #include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/grid_defs.h" #include "nvim/macros_defs.h" -/// Types of dialogs passed to do_dialog(). -enum { - VIM_GENERIC = 0, - VIM_ERROR = 1, - VIM_WARNING = 2, - VIM_INFO = 3, - VIM_QUESTION = 4, - VIM_LAST_TYPE = 4, ///< sentinel value -}; - -/// Return values for functions like vim_dialogyesno() -enum { - VIM_YES = 2, - VIM_NO = 3, - VIM_CANCEL = 4, - VIM_ALL = 5, - VIM_DISCARDALL = 6, -}; - -enum { MSG_HIST = 0x1000, }; ///< special attribute addition: Put message in history - typedef struct { String text; int attr; @@ -46,14 +23,3 @@ typedef struct msg_hist { bool multiline; ///< Multiline message. HlMessage multiattr; ///< multiattr message. } MessageHistoryEntry; - -// Prefer using semsg(), because perror() may send the output to the wrong -// destination and mess up the screen. -#define PERROR(msg) (void)semsg("%s: %s", (msg), strerror(errno)) - -#ifndef MSWIN -/// Headless (no UI) error message handler. -# define os_errmsg(str) fprintf(stderr, "%s", (str)) -/// Headless (no UI) message handler. -# define os_msg(str) printf("%s", (str)) -#endif diff --git a/src/nvim/option.h b/src/nvim/option.h index 44cba70302..2e4186fe7f 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include // IWYU pragma: keep diff --git a/src/nvim/os/lang.c b/src/nvim/os/lang.c index 17d179a56a..20b60150ee 100644 --- a/src/nvim/os/lang.c +++ b/src/nvim/os/lang.c @@ -20,6 +20,7 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/garray.h" #include "nvim/gettext.h" +#include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" #include "nvim/message.h" -- cgit From 6abdc1ac1f904173d01efcf440d1460c001bc299 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 18 Dec 2023 09:05:59 +0800 Subject: refactor: split WIN_EXECUTE() into two functions (#26627) --- src/clint.py | 1 - src/nvim/api/window.c | 6 ++-- src/nvim/eval/window.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++---- src/nvim/eval/window.h | 70 ++++++++----------------------------------- 4 files changed, 90 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 446593303b..51155f0038 100755 --- a/src/clint.py +++ b/src/clint.py @@ -912,7 +912,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/eval/typval.h", "src/nvim/eval/typval_defs.h", "src/nvim/eval/userfunc.h", - "src/nvim/eval/window.h", "src/nvim/event/libuv_process.h", "src/nvim/event/loop.h", "src/nvim/event/process.h", diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index d18971c756..7321d52e17 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -435,10 +435,12 @@ Object nvim_win_call(Window window, LuaRef fun, Error *err) try_start(); Object res = OBJECT_INIT; - WIN_EXECUTE(win, tabpage, { + win_execute_T win_execute_args; + if (win_execute_before(&win_execute_args, win, tabpage)) { Array args = ARRAY_DICT_INIT; res = nlua_call_ref(fun, NULL, args, true, err); - }); + } + win_execute_after(&win_execute_args); try_end(err); return res; } diff --git a/src/nvim/eval/window.c b/src/nvim/eval/window.c index e0abbad477..d1ee2ea356 100644 --- a/src/nvim/eval/window.c +++ b/src/nvim/eval/window.c @@ -9,7 +9,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/cursor.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" @@ -19,9 +18,12 @@ #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" +#include "nvim/mark.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/move.h" +#include "nvim/option_vars.h" +#include "nvim/os/fs.h" #include "nvim/pos_defs.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" @@ -480,6 +482,68 @@ void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) rettv->vval.v_number = nr; } +/// Switch to a window for executing user code. +/// Caller must call win_execute_after() later regardless of return value. +/// +/// @return whether switching the window succeded. +bool win_execute_before(win_execute_T *args, win_T *wp, tabpage_T *tp) +{ + args->wp = wp; + args->curpos = wp->w_cursor; + args->cwd_status = FAIL; + args->apply_acd = false; + + // Getting and setting directory can be slow on some systems, only do + // this when the current or target window/tab have a local directory or + // 'acd' is set. + if (curwin != wp + && (curwin->w_localdir != NULL || wp->w_localdir != NULL + || (curtab != tp && (curtab->tp_localdir != NULL || tp->tp_localdir != NULL)) + || p_acd)) { + args->cwd_status = os_dirname(args->cwd, MAXPATHL); + } + + // If 'acd' is set, check we are using that directory. If yes, then + // apply 'acd' afterwards, otherwise restore the current directory. + if (args->cwd_status == OK && p_acd) { + do_autochdir(); + char autocwd[MAXPATHL]; + if (os_dirname(autocwd, MAXPATHL) == OK) { + args->apply_acd = strcmp(args->cwd, autocwd) == 0; + } + } + + if (switch_win_noblock(&args->switchwin, wp, tp, true) == OK) { + check_cursor(); + return true; + } + return false; +} + +/// Restore the previous window after executing user code. +void win_execute_after(win_execute_T *args) +{ + restore_win_noblock(&args->switchwin, true); + + if (args->apply_acd) { + do_autochdir(); + } else if (args->cwd_status == OK) { + os_chdir(args->cwd); + } + + // Update the status line if the cursor moved. + if (win_valid(args->wp) && !equalpos(args->curpos, args->wp->w_cursor)) { + args->wp->w_redr_status = true; + } + + // In case the command moved the cursor or changed the Visual area, + // check it is valid. + check_cursor(); + if (VIsual_active) { + check_pos(curbuf, &VIsual); + } +} + /// "win_execute(win_id, command)" function void f_win_execute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { @@ -494,7 +558,11 @@ void f_win_execute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - WIN_EXECUTE(wp, tp, execute_common(argvars, rettv, 1)); + win_execute_T win_execute_args; + if (win_execute_before(&win_execute_args, wp, tp)) { + execute_common(argvars, rettv, 1); + } + win_execute_after(&win_execute_args); } /// "win_findbuf()" function @@ -914,16 +982,16 @@ int switch_win_noblock(switchwin_T *switchwin, win_T *win, tabpage_T *tp, bool n return OK; } -// Restore current tabpage and window saved by switch_win(), if still valid. -// When "no_display" is true the display won't be affected, no redraw is -// triggered. +/// Restore current tabpage and window saved by switch_win(), if still valid. +/// When "no_display" is true the display won't be affected, no redraw is +/// triggered. void restore_win(switchwin_T *switchwin, bool no_display) { restore_win_noblock(switchwin, no_display); unblock_autocmds(); } -// As restore_win() but without unblocking autocommands. +/// As restore_win() but without unblocking autocommands. void restore_win_noblock(switchwin_T *switchwin, bool no_display) { if (switchwin->sw_curtab != NULL && valid_tabpage(switchwin->sw_curtab)) { diff --git a/src/nvim/eval/window.h b/src/nvim/eval/window.h index ed879c895a..1b2817edf0 100644 --- a/src/nvim/eval/window.h +++ b/src/nvim/eval/window.h @@ -1,20 +1,12 @@ #pragma once #include -#include -#include "nvim/buffer.h" #include "nvim/buffer_defs.h" -#include "nvim/cursor.h" -#include "nvim/eval/typval_defs.h" -#include "nvim/globals.h" -#include "nvim/mark.h" -#include "nvim/option_defs.h" -#include "nvim/option_vars.h" -#include "nvim/os/fs.h" +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep +#include "nvim/os/os_defs.h" #include "nvim/pos_defs.h" -#include "nvim/vim_defs.h" -#include "nvim/window.h" +#include "nvim/types_defs.h" // IWYU pragma: keep /// Structure used by switch_win() to pass values to restore_win() typedef struct { @@ -24,53 +16,15 @@ typedef struct { bool sw_visual_active; } switchwin_T; -/// Execute a block of code in the context of window `wp` in tabpage `tp`. -/// Ensures the status line is redrawn and cursor position is valid if it is moved. -#define WIN_EXECUTE(wp, tp, block) \ - do { \ - win_T *const wp_ = (wp); \ - const pos_T curpos_ = wp_->w_cursor; \ - char cwd_[MAXPATHL]; \ - char autocwd_[MAXPATHL]; \ - bool apply_acd_ = false; \ - int cwd_status_ = FAIL; \ - /* Getting and setting directory can be slow on some systems, only do */ \ - /* this when the current or target window/tab have a local directory or */ \ - /* 'acd' is set. */ \ - if (curwin != wp \ - && (curwin->w_localdir != NULL || wp->w_localdir != NULL \ - || (curtab != tp && (curtab->tp_localdir != NULL || tp->tp_localdir != NULL)) \ - || p_acd)) { \ - cwd_status_ = os_dirname(cwd_, MAXPATHL); \ - } \ - /* If 'acd' is set, check we are using that directory. If yes, then */ \ - /* apply 'acd' afterwards, otherwise restore the current directory. */ \ - if (cwd_status_ == OK && p_acd) { \ - do_autochdir(); \ - apply_acd_ = os_dirname(autocwd_, MAXPATHL) == OK && strcmp(cwd_, autocwd_) == 0; \ - } \ - switchwin_T switchwin_; \ - if (switch_win_noblock(&switchwin_, wp_, (tp), true) == OK) { \ - check_cursor(); \ - block; \ - } \ - restore_win_noblock(&switchwin_, true); \ - if (apply_acd_) { \ - do_autochdir(); \ - } else if (cwd_status_ == OK) { \ - os_chdir(cwd_); \ - } \ - /* Update the status line if the cursor moved. */ \ - if (win_valid(wp_) && !equalpos(curpos_, wp_->w_cursor)) { \ - wp_->w_redr_status = true; \ - } \ - /* In case the command moved the cursor or changed the Visual area, */ \ - /* check it is valid. */ \ - check_cursor(); \ - if (VIsual_active) { \ - check_pos(curbuf, &VIsual); \ - } \ - } while (false) +/// Structure used by win_execute_before() to pass values to win_execute_after() +typedef struct { + win_T *wp; + pos_T curpos; + char cwd[MAXPATHL]; + int cwd_status; + bool apply_acd; + switchwin_T switchwin; +} win_execute_T; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/window.h.generated.h" -- cgit From d956bc63795ff7a6ff54ad942a7483a5ef76e650 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 18 Dec 2023 10:15:23 +0800 Subject: fix(options): setting 'scroll' with resized grid (#26628) --- src/nvim/option.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 6237b11de2..ce4ca92ae8 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2796,7 +2796,8 @@ static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, char *e } } - if ((curwin->w_p_scr <= 0 || (curwin->w_p_scr > curwin->w_height && curwin->w_height > 0)) + if ((curwin->w_p_scr <= 0 + || (curwin->w_p_scr > curwin->w_height_inner && curwin->w_height_inner > 0)) && full_screen) { if (pp == &(curwin->w_p_scr)) { if (curwin->w_p_scr != 0) { @@ -2806,8 +2807,8 @@ static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, char *e } else if (curwin->w_p_scr <= 0) { // If 'scroll' became invalid because of a side effect silently adjust it. curwin->w_p_scr = 1; - } else { // curwin->w_p_scr > curwin->w_height - curwin->w_p_scr = curwin->w_height; + } else { // curwin->w_p_scr > curwin->w_height_inner + curwin->w_p_scr = curwin->w_height_inner; } } if ((p_sj < -100 || p_sj >= Rows) && full_screen) { -- cgit From 7d279a09e0fbdf939d8747270cc642250365ad6c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 18 Dec 2023 12:14:37 +0800 Subject: fix(lua): handle array with holes in luaeval() (#26630) --- src/nvim/lua/converter.c | 57 ++++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index e26e38f577..468fe19cf9 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -170,11 +170,12 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) /// Helper structure for nlua_pop_typval typedef struct { - typval_T *tv; ///< Location where conversion result is saved. - bool container; ///< True if tv is a container. - bool special; ///< If true then tv is a _VAL part of special dictionary - ///< that represents mapping. - int idx; ///< Container index (used to detect self-referencing structures). + typval_T *tv; ///< Location where conversion result is saved. + size_t list_len; ///< Maximum length when tv is a list. + bool container; ///< True if tv is a container. + bool special; ///< If true then tv is a _VAL part of special dictionary + ///< that represents mapping. + int idx; ///< Container index (used to detect self-referencing structures). } TVPopStackItem; /// Convert lua object to Vimscript typval_T @@ -192,7 +193,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) const int initial_size = lua_gettop(lstate); kvec_withinit_t(TVPopStackItem, 2) stack = KV_INITIAL_VALUE; kvi_init(stack); - kvi_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 })); + kvi_push(stack, ((TVPopStackItem){ .tv = ret_tv })); while (ret && kv_size(stack)) { if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { semsg(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3); @@ -231,19 +232,14 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) }); kvi_push(stack, cur); tv_list_append_list(cur.tv->vval.v_list, kv_pair); - cur = (TVPopStackItem) { - .tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)), - .container = false, - .special = false, - .idx = 0, - }; + cur = (TVPopStackItem){ .tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)) }; } else { dictitem_T *const di = tv_dict_item_alloc_len(s, len); if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) { abort(); } kvi_push(stack, cur); - cur = (TVPopStackItem) { &di->di_tv, false, false, 0 }; + cur = (TVPopStackItem){ .tv = &di->di_tv }; } } else { lua_pop(lstate, 1); @@ -251,23 +247,18 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) } } else { assert(cur.tv->v_type == VAR_LIST); - lua_rawgeti(lstate, -1, tv_list_len(cur.tv->vval.v_list) + 1); - if (lua_isnil(lstate, -1)) { - lua_pop(lstate, 2); + if ((size_t)tv_list_len(cur.tv->vval.v_list) == cur.list_len) { + lua_pop(lstate, 1); continue; } + lua_rawgeti(lstate, -1, tv_list_len(cur.tv->vval.v_list) + 1); // Not populated yet, need to create list item to push. tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) { .v_type = VAR_UNKNOWN, }); kvi_push(stack, cur); // TODO(ZyX-I): Use indexes, here list item *will* be reallocated. - cur = (TVPopStackItem) { - .tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)), - .container = false, - .special = false, - .idx = 0, - }; + cur = (TVPopStackItem){ .tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)) }; } } assert(!cur.container); @@ -331,6 +322,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) cur.tv->vval.v_list = tv_list_alloc((ptrdiff_t)table_props.maxidx); cur.tv->vval.v_list->lua_table_ref = table_ref; tv_list_ref(cur.tv->vval.v_list); + cur.list_len = table_props.maxidx; if (table_props.maxidx != 0) { cur.container = true; cur.idx = lua_gettop(lstate); @@ -354,6 +346,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) cur.tv = &val_di->di_tv; cur.tv->vval.v_list->lua_table_ref = table_ref; assert(cur.tv->v_type == VAR_LIST); + cur.list_len = table_props.string_keys_num; } else { cur.tv->v_type = VAR_DICT; cur.tv->vval.v_dict = tv_dict_alloc(); @@ -371,9 +364,8 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv) cur.tv->vval.v_float = (float_T)table_props.val; break; case kObjectTypeNil: - emsg(_("E5100: Cannot convert given lua table: table " - "should either have a sequence of positive integer keys " - "or contain only string keys")); + emsg(_("E5100: Cannot convert given lua table: table should " + "contain either only integer keys or only string keys")); ret = false; break; default: @@ -1077,7 +1069,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) const int initial_size = lua_gettop(lstate); kvec_withinit_t(ObjPopStackItem, 2) stack = KV_INITIAL_VALUE; kvi_init(stack); - kvi_push(stack, ((ObjPopStackItem) { &ret, false })); + kvi_push(stack, ((ObjPopStackItem){ .obj = &ret })); while (!ERROR_SET(err) && kv_size(stack)) { ObjPopStackItem cur = kv_pop(stack); if (cur.container) { @@ -1087,8 +1079,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) } if (cur.obj->type == kObjectTypeDictionary) { // stack: …, dict, key - if (cur.obj->data.dictionary.size - == cur.obj->data.dictionary.capacity) { + if (cur.obj->data.dictionary.size == cur.obj->data.dictionary.capacity) { lua_pop(lstate, 2); continue; } @@ -1112,10 +1103,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) .size = len, }; kvi_push(stack, cur); - cur = (ObjPopStackItem) { - .obj = &cur.obj->data.dictionary.items[idx].value, - .container = false, - }; + cur = (ObjPopStackItem){ .obj = &cur.obj->data.dictionary.items[idx].value }; } else { // stack: …, dict lua_pop(lstate, 1); @@ -1130,10 +1118,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err) const size_t idx = cur.obj->data.array.size++; lua_rawgeti(lstate, -1, (int)idx + 1); kvi_push(stack, cur); - cur = (ObjPopStackItem) { - .obj = &cur.obj->data.array.items[idx], - .container = false, - }; + cur = (ObjPopStackItem){ .obj = &cur.obj->data.array.items[idx] }; } } assert(!cur.container); -- cgit From 6cb78e2d1c4c6c63c628c965076a07ce5f7adbb6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 16 Dec 2023 22:14:28 +0100 Subject: docs: add style rule regarding initialization Specifically, specify that each initialization should be done on a separate line. --- src/nvim/change.c | 10 +++--- src/nvim/drawscreen.c | 2 +- src/nvim/edit.c | 5 ++- src/nvim/eval.c | 6 ++-- src/nvim/eval/funcs.c | 11 +++--- src/nvim/eval/userfunc.c | 6 ++-- src/nvim/eval/window.c | 3 +- src/nvim/ex_cmds.c | 12 ++++--- src/nvim/extmark.c | 6 ++-- src/nvim/fold.c | 15 ++++---- src/nvim/globals.h | 6 ++-- src/nvim/grid.c | 11 +++--- src/nvim/highlight.c | 9 +++-- src/nvim/indent.c | 90 ++++++++++++++++++------------------------------ src/nvim/insexpand.c | 2 +- src/nvim/keycodes.c | 3 +- src/nvim/lua/stdlib.c | 6 ++-- src/nvim/lua/xdiff.c | 3 +- src/nvim/marktree.c | 45 ++++++++++++++++-------- src/nvim/mbyte.c | 3 +- src/nvim/memory.c | 6 ++-- src/nvim/move.c | 8 +++-- src/nvim/ops.c | 16 ++++----- src/nvim/optionstr.c | 3 +- src/nvim/os/input.c | 3 +- src/nvim/os/shell.c | 9 +++-- src/nvim/strings.c | 10 ++++-- src/nvim/terminal.c | 10 +++--- src/nvim/tui/tui.c | 9 +++-- src/nvim/ui.c | 3 +- src/nvim/ui_client.c | 4 ++- src/nvim/ui_compositor.c | 3 +- src/nvim/undo.c | 7 ++-- src/nvim/window.c | 12 ++++--- src/nvim/winfloat.c | 7 ++-- 35 files changed, 202 insertions(+), 162 deletions(-) (limited to 'src') diff --git a/src/nvim/change.c b/src/nvim/change.c index c528ffba20..622eb3b9a5 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -2121,10 +2121,8 @@ int get_last_leader_offset(char *line, char **flags) int result = -1; int j; int lower_check_bound = 0; - char *string; char *com_leader; char *com_flags; - char *list; char part_buf[COM_MAX_LEN]; // buffer for one option part // Repeat to match several nested comment strings. @@ -2132,13 +2130,13 @@ int get_last_leader_offset(char *line, char **flags) while (--i >= lower_check_bound) { // scan through the 'comments' option for a match int found_one = false; - for (list = curbuf->b_p_com; *list;) { + for (char *list = curbuf->b_p_com; *list;) { char *flags_save = list; // Get one option part into part_buf[]. Advance list to next one. // put string at start of string. (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ","); - string = vim_strchr(part_buf, ':'); + char *string = vim_strchr(part_buf, ':'); if (string == NULL) { // If everything is fine, this cannot actually // happen. continue; @@ -2216,14 +2214,14 @@ int get_last_leader_offset(char *line, char **flags) } int len1 = (int)strlen(com_leader); - for (list = curbuf->b_p_com; *list;) { + for (char *list = curbuf->b_p_com; *list;) { char *flags_save = list; (void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ","); if (flags_save == com_flags) { continue; } - string = vim_strchr(part_buf2, ':'); + char *string = vim_strchr(part_buf2, ':'); string++; while (ascii_iswhite(*string)) { string++; diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 09a0a43e2f..94eeb9bc77 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -928,7 +928,6 @@ int showmode(void) bool can_show_mode = (p_ch != 0 || ui_has(kUIMessages)); if ((do_mode || reg_recording != 0) && can_show_mode) { - int sub_attr; if (skip_showmode()) { return 0; // show mode later } @@ -955,6 +954,7 @@ int showmode(void) lines_left = 0; if (do_mode) { + int sub_attr; msg_puts_attr("--", attr); // CTRL-X in Insert mode if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) { diff --git a/src/nvim/edit.c b/src/nvim/edit.c index ba2885a162..0fcb665f0f 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -3008,7 +3008,6 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) int try_match; int try_match_word; char *p; - char *line; bool icase; if (keytyped == NUL) { @@ -3150,7 +3149,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) // Just completed a word, check if it starts with "look". // search back for the start of a word. - line = get_cursor_line_ptr(); + char *line = get_cursor_line_ptr(); for (s = line + curwin->w_cursor.col; s > line; s = n) { n = mb_prevptr(line, s); if (!vim_iswordp(n)) { @@ -3169,7 +3168,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) if (keytyped == (int)(uint8_t)p[-1] || (icase && keytyped < 256 && TOLOWER_LOC(keytyped) == TOLOWER_LOC((uint8_t)p[-1]))) { - line = get_cursor_pos_ptr(); + char *line = get_cursor_pos_ptr(); assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX); if ((curwin->w_cursor.col == (colnr_T)(p - look) || !vim_iswordc((uint8_t)line[-(p - look) - 1])) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d8134c2360..7d869881e8 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2863,7 +2863,8 @@ static int eval5(char **arg, typval_T *rettv, evalarg_T *const evalarg) } else { bool error = false; varnumber_T n1, n2; - float_T f1 = 0, f2 = 0; + float_T f1 = 0; + float_T f2 = 0; if (rettv->v_type == VAR_FLOAT) { f1 = rettv->vval.v_float; @@ -2954,7 +2955,8 @@ static int eval6(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan } varnumber_T n1, n2; - float_T f1 = 0, f2 = 0; + float_T f1 = 0; + float_T f2 = 0; bool error = false; const bool evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE); if (evaluate) { diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index ea68c010d6..81ae208560 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -4054,8 +4054,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) bool clear_env = false; bool overlapped = false; ChannelStdinMode stdin_mode = kChannelStdinPipe; - CallbackReader on_stdout = CALLBACK_READER_INIT, - on_stderr = CALLBACK_READER_INIT; + CallbackReader on_stdout = CALLBACK_READER_INIT; + CallbackReader on_stderr = CALLBACK_READER_INIT; Callback on_exit = CALLBACK_NONE; char *cwd = NULL; dictitem_T *job_env = NULL; @@ -4118,7 +4118,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } } - uint16_t width = 0, height = 0; + uint16_t width = 0; + uint16_t height = 0; char *term_name = NULL; if (pty) { @@ -8553,8 +8554,8 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - CallbackReader on_stdout = CALLBACK_READER_INIT, - on_stderr = CALLBACK_READER_INIT; + CallbackReader on_stdout = CALLBACK_READER_INIT; + CallbackReader on_stderr = CALLBACK_READER_INIT; Callback on_exit = CALLBACK_NONE; dict_T *job_opts = NULL; const char *cwd = "."; diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index ebc84922cb..cce02e6daf 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -105,7 +105,6 @@ static int get_function_args(char **argp, char endchar, garray_T *newargs, int * char *arg = *argp; char *p = arg; uint8_t c; - int i; if (newargs != NULL) { ga_init(newargs, (int)sizeof(char *), 3); @@ -147,7 +146,7 @@ static int get_function_args(char **argp, char endchar, garray_T *newargs, int * arg = xstrdup(arg); // Check for duplicate argument name. - for (i = 0; i < newargs->ga_len; i++) { + for (int i = 0; i < newargs->ga_len; i++) { if (strcmp(((char **)(newargs->ga_data))[i], arg) == 0) { semsg(_("E853: Duplicate argument name: %s"), arg); xfree(arg); @@ -922,7 +921,6 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett static int depth = 0; dictitem_T *v; int fixvar_idx = 0; // index in fc_fixvar[] - int ai; bool islambda = false; char numbuf[NUMBUFLEN]; char *name; @@ -1025,7 +1023,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett bool isdefault = false; typval_T def_rettv; - ai = i - fp->uf_args.ga_len; + int ai = i - fp->uf_args.ga_len; if (ai < 0) { // named argument a:name name = FUNCARG(fp, i); diff --git a/src/nvim/eval/window.c b/src/nvim/eval/window.c index d1ee2ea356..02f214f262 100644 --- a/src/nvim/eval/window.c +++ b/src/nvim/eval/window.c @@ -710,7 +710,8 @@ void f_win_splitmove(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - int flags = 0, size = 0; + int flags = 0; + int size = 0; if (argvars[2].v_type != VAR_UNKNOWN) { dict_T *d; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 96429c96f7..a0e9b537e8 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -618,7 +618,8 @@ void ex_sort(exarg_T *eap) goto sortend; } - bcount_t old_count = 0, new_count = 0; + bcount_t old_count = 0; + bcount_t new_count = 0; // Insert the lines in the sorted order below the last one. linenr_T lnum = eap->line2; @@ -3303,7 +3304,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n .do_number = false, .do_ic = kSubHonorOptions }; - char *pat = NULL, *sub = NULL; // init for GCC + char *pat = NULL; + char *sub = NULL; // init for GCC int delimiter; bool has_second_delim = false; int sublen; @@ -3501,7 +3503,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n colnr_T copycol; colnr_T matchcol; colnr_T prev_matchcol = MAXCOL; - char *new_end, *new_start = NULL; + char *new_end; + char *new_start = NULL; int new_start_len = 0; char *p1; bool did_sub = false; @@ -3971,7 +3974,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n // TODO(bfredl): this has some robustness issues, look into later. bcount_t replaced_bytes = 0; - lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0]; + lpos_T start = regmatch.startpos[0]; + lpos_T end = regmatch.endpos[0]; for (i = 0; i < nmatch - 1; i++) { replaced_bytes += (bcount_t)strlen(ml_get((linenr_T)(lnum_start + i))) + 1; } diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index f914137ccc..f305b6d506 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -435,8 +435,10 @@ void extmark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount, return; } bcount_t start_byte = ml_find_line_or_offset(buf, line1, NULL, true); - bcount_t old_byte = 0, new_byte = 0; - int old_row, new_row; + bcount_t old_byte = 0; + bcount_t new_byte = 0; + int old_row; + int new_row; if (amount == MAXLNUM) { old_row = line2 - line1 + 1; // TODO(bfredl): ej kasta? diff --git a/src/nvim/fold.c b/src/nvim/fold.c index e372b9f461..9e90ab9439 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -849,7 +849,6 @@ void foldUpdateAll(win_T *win) int foldMoveTo(const bool updown, const int dir, const int count) { int retval = FAIL; - linenr_T lnum; fold_T *fp; checkupdate(curwin); @@ -908,7 +907,7 @@ int foldMoveTo(const bool updown, const int dir, const int count) if (dir == FORWARD) { // to start of next fold if there is one if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len) { - lnum = fp[1].fd_top + lnum_off; + linenr_T lnum = fp[1].fd_top + lnum_off; if (lnum > curwin->w_cursor.lnum) { lnum_found = lnum; } @@ -916,7 +915,7 @@ int foldMoveTo(const bool updown, const int dir, const int count) } else { // to end of previous fold if there is one if (fp > (fold_T *)gap->ga_data) { - lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1; + linenr_T lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1; if (lnum < curwin->w_cursor.lnum) { lnum_found = lnum; } @@ -926,12 +925,12 @@ int foldMoveTo(const bool updown, const int dir, const int count) // Open fold found, set cursor to its start/end and then check // nested folds. if (dir == FORWARD) { - lnum = fp->fd_top + lnum_off + fp->fd_len - 1; + linenr_T lnum = fp->fd_top + lnum_off + fp->fd_len - 1; if (lnum > curwin->w_cursor.lnum) { lnum_found = lnum; } } else { - lnum = fp->fd_top + lnum_off; + linenr_T lnum = fp->fd_top + lnum_off; if (lnum < curwin->w_cursor.lnum) { lnum_found = lnum; } @@ -999,7 +998,6 @@ void foldAdjustVisual(void) } pos_T *start, *end; - char *ptr; if (ltoreq(VIsual, curwin->w_cursor)) { start = &VIsual; @@ -1016,7 +1014,7 @@ void foldAdjustVisual(void) return; } - ptr = ml_get(end->lnum); + char *ptr = ml_get(end->lnum); end->col = (colnr_T)strlen(ptr); if (end->col > 0 && *p_sel == 'o') { end->col--; @@ -2802,7 +2800,8 @@ void foldMoveRange(win_T *const wp, garray_T *gap, const linenr_T line1, const l // Case 5 or 6: changes rely on whether there are folds between the end of // this fold and "dest". size_t move_start = FOLD_INDEX(fp, gap); - size_t move_end = 0, dest_index = 0; + size_t move_end = 0; + size_t dest_index = 0; for (; VALID_FOLD(fp, gap) && fp->fd_top <= dest; fp++) { if (fp->fd_top <= line2) { // 5, or 6 diff --git a/src/nvim/globals.h b/src/nvim/globals.h index c0fa63818e..e153b03bc1 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -124,7 +124,7 @@ EXTERN bool redraw_cmdline INIT( = false); // cmdline must be redrawn EXTERN bool redraw_mode INIT( = false); // mode 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 int cmdline_star INIT( = 0); // 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 @@ -591,9 +591,9 @@ EXTERN int reg_executing INIT( = 0); // register being executed or zero EXTERN bool pending_end_reg_executing INIT( = false); EXTERN int reg_recorded INIT( = 0); // last recorded register or zero -EXTERN int no_mapping INIT( = false); // currently no mapping allowed +EXTERN int no_mapping INIT( = 0); // currently no mapping allowed EXTERN int no_zero_mapping INIT( = 0); // mapping zero not allowed -EXTERN int allow_keys INIT( = false); // allow key codes when no_mapping is set +EXTERN int allow_keys INIT( = 0); // allow key codes when no_mapping is set EXTERN int no_u_sync INIT( = 0); // Don't call u_sync() EXTERN int u_sync_once INIT( = 0); // Call u_sync() once when evaluating // an expression. diff --git a/src/nvim/grid.c b/src/nvim/grid.c index 58884e7f72..9830f25dcb 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -538,7 +538,8 @@ void grid_line_flush_if_valid_row(void) void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr) { - int row_off = 0, col_off = 0; + int row_off = 0; + int col_off = 0; grid_adjust(&grid, &row_off, &col_off); start_row += row_off; end_row += row_off; @@ -650,8 +651,6 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol { bool redraw_next; // redraw_this for next character bool clear_next = false; - int char_cells; // 1: normal char - // 2: occupies two display cells assert(0 <= row && row < grid->rows); // TODO(bfredl): check all callsites and eliminate // Check for illegal col, just in case @@ -703,10 +702,12 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol redraw_next = grid_char_needs_redraw(grid, col, (size_t)col + off_to, endcol - col); - int start_dirty = -1, end_dirty = 0; + int start_dirty = -1; + int end_dirty = 0; while (col < endcol) { - char_cells = 1; + int char_cells = 1; // 1: normal char + // 2: occupies two display cells if (col + 1 < endcol && linebuf_char[col + 1] == 0) { char_cells = 2; } diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 141761c52e..6684a20607 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -713,7 +713,8 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through) static int rgb_blend(int ratio, int rgb1, int rgb2) { - int a = ratio, b = 100 - ratio; + int a = ratio; + int b = 100 - ratio; int r1 = (rgb1 & 0xFF0000) >> 16; int g1 = (rgb1 & 0x00FF00) >> 8; int b1 = (rgb1 & 0x0000FF) >> 0; @@ -940,7 +941,11 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e { #define HAS_KEY_X(d, key) HAS_KEY(d, highlight, key) HlAttrs hlattrs = HLATTRS_INIT; - int32_t fg = -1, bg = -1, ctermfg = -1, ctermbg = -1, sp = -1; + int32_t fg = -1; + int32_t bg = -1; + int32_t ctermfg = -1; + int32_t ctermbg = -1; + int32_t sp = -1; int blend = -1; int16_t mask = 0; int16_t cterm_mask = 0; diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 925317e7cb..61422561e0 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -53,15 +53,13 @@ bool tabstop_set(char *var, colnr_T **array) { int valcount = 1; - int t; - char *cp; if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) { *array = NULL; return true; } - for (cp = var; *cp != NUL; cp++) { + for (char *cp = var; *cp != NUL; cp++) { if (cp == var || cp[-1] == ',') { char *end; @@ -89,8 +87,8 @@ bool tabstop_set(char *var, colnr_T **array) *array = (colnr_T *)xmalloc((unsigned)(valcount + 1) * sizeof(int)); (*array)[0] = (colnr_T)valcount; - t = 1; - for (cp = var; *cp != NUL;) { + int t = 1; + for (char *cp = var; *cp != NUL;) { int n = atoi(cp); // Catch negative values, overflow and ridiculous big values. @@ -171,14 +169,13 @@ int tabstop_at(colnr_T col, OptInt ts, const colnr_T *vts) colnr_T tabstop_start(colnr_T col, int ts, colnr_T *vts) { colnr_T tabcol = 0; - int t; if (vts == NULL || vts[0] == 0) { return ((col / ts) * ts); } const int tabcount = vts[0]; - for (t = 1; t <= tabcount; t++) { + for (int t = 1; t <= tabcount; t++) { tabcol += vts[t]; if (tabcol > col) { return (tabcol - vts[t]); @@ -258,8 +255,6 @@ void tabstop_fromto(colnr_T start_col, colnr_T end_col, int ts_arg, const colnr_ /// See if two tabstop arrays contain the same values. bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2) { - int t; - if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) { return false; } @@ -270,7 +265,7 @@ bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2) return false; } - for (t = 1; t <= ts1[0]; t++) { + for (int t = 1; t <= ts1[0]; t++) { if (ts1[t] != ts2[t]) { return false; } @@ -282,15 +277,12 @@ bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2) /// Copy a tabstop array, allocating space for the new array. int *tabstop_copy(const int *oldts) { - int *newts; - int t; - if (oldts == 0) { return 0; } - newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(int)); - for (t = 0; t <= oldts[0]; t++) { + int *newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(int)); + for (int t = 0; t <= oldts[0]; t++) { newts[t] = oldts[t]; } @@ -431,25 +423,22 @@ int get_indent_str_vtab(const char *ptr, OptInt ts, colnr_T *vts, bool list) return count; } -// Set the indent of the current line. -// Leaves the cursor on the first non-blank in the line. -// Caller must take care of undo. -// "flags": -// SIN_CHANGED: call changed_bytes() if the line was changed. -// SIN_INSERT: insert the indent in front of the line. -// SIN_UNDO: save line for undo before changing it. -// SIN_NOMARK: don't move extmarks (because just after ml_append or something) -// @param size measured in spaces -// Returns true if the line was changed. +/// Set the indent of the current line. +/// Leaves the cursor on the first non-blank in the line. +/// Caller must take care of undo. +/// "flags": +/// SIN_CHANGED: call changed_bytes() if the line was changed. +/// SIN_INSERT: insert the indent in front of the line. +/// SIN_UNDO: save line for undo before changing it. +/// SIN_NOMARK: don't move extmarks (because just after ml_append or something) +/// @param size measured in spaces +/// +/// @return true if the line was changed. int set_indent(int size, int flags) { - char *p; char *newline; char *oldline; char *s; - int todo; - int ind_len; // Measured in characters. - int line_len; int doit = false; int ind_done = 0; // Measured in spaces. int tab_pad; @@ -460,9 +449,9 @@ int set_indent(int size, int flags) // First check if there is anything to do and compute the number of // characters needed for the indent. - todo = size; - ind_len = 0; - p = oldline = get_cursor_line_ptr(); + int todo = size; + int ind_len = 0; // Measured in characters. + char *p = oldline = get_cursor_line_ptr(); // Calculate the buffer size for the new indent, and check to see if it // isn't already set. @@ -560,7 +549,7 @@ int set_indent(int size, int flags) } else { p = skipwhite(p); } - line_len = (int)strlen(p) + 1; + int line_len = (int)strlen(p) + 1; // If 'preserveindent' and 'expandtab' are both set keep the original // characters and allocate accordingly. We will fill the rest with spaces @@ -933,23 +922,18 @@ static void emsg_text_too_long(void) /// ":retab". void ex_retab(exarg_T *eap) { - linenr_T lnum; bool got_tab = false; int num_spaces = 0; - int num_tabs; - int len; int start_col = 0; // For start of white-space string int64_t start_vcol = 0; // For start of white-space string - int old_len; char *new_line = (char *)1; // init to non-NULL colnr_T *new_vts_array = NULL; char *new_ts_str; // string value of tab argument - int save_list; linenr_T first_line = 0; // first changed line linenr_T last_line = 0; // last changed line - save_list = curwin->w_p_list; + int save_list = curwin->w_p_list; curwin->w_p_list = 0; // don't want list mode here new_ts_str = eap->arg; @@ -969,7 +953,7 @@ void ex_retab(exarg_T *eap) } else { new_ts_str = xmemdupz(new_ts_str, (size_t)(eap->arg - new_ts_str)); } - for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { + for (linenr_T lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { char *ptr = ml_get(lnum); int col = 0; int64_t vcol = 0; @@ -991,8 +975,8 @@ void ex_retab(exarg_T *eap) // Retabulate this string of white-space // len is virtual length of white string - len = num_spaces = (int)(vcol - start_vcol); - num_tabs = 0; + int len = num_spaces = (int)(vcol - start_vcol); + int num_tabs = 0; if (!curbuf->b_p_et) { int t, s; @@ -1014,7 +998,7 @@ void ex_retab(exarg_T *eap) // len is actual number of white characters used len = num_spaces + num_tabs; - old_len = (int)strlen(ptr); + int old_len = (int)strlen(ptr); const int new_len = old_len - col + start_col + len + 1; if (new_len <= 0 || new_len >= MAXCOL) { emsg_text_too_long(); @@ -1110,19 +1094,14 @@ void ex_retab(exarg_T *eap) /// Get indent level from 'indentexpr'. int get_expr_indent(void) { - int indent = -1; - pos_T save_pos; - colnr_T save_curswant; - int save_set_curswant; - int save_State; int use_sandbox = was_set_insecurely(curwin, kOptIndentexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Save and restore cursor position and curswant, in case it was changed // * via :normal commands. - save_pos = curwin->w_cursor; - save_curswant = curwin->w_curswant; - save_set_curswant = curwin->w_set_curswant; + pos_T save_pos = curwin->w_cursor; + colnr_T save_curswant = curwin->w_curswant; + int save_set_curswant = curwin->w_set_curswant; set_vim_var_nr(VV_LNUM, (varnumber_T)curwin->w_cursor.lnum); if (use_sandbox) { @@ -1134,7 +1113,7 @@ int get_expr_indent(void) // Need to make a copy, the 'indentexpr' option could be changed while // evaluating it. char *inde_copy = xstrdup(curbuf->b_p_inde); - indent = (int)eval_to_number(inde_copy); + int indent = (int)eval_to_number(inde_copy); xfree(inde_copy); if (use_sandbox) { @@ -1146,7 +1125,7 @@ int get_expr_indent(void) // Restore the cursor position so that 'indentexpr' doesn't need to. // Pretend to be in Insert mode, allow cursor past end of line for "o" // command. - save_State = State; + int save_State = State; State = MODE_INSERT; curwin->w_cursor = save_pos; curwin->w_curswant = save_curswant; @@ -1187,7 +1166,6 @@ int get_lisp_indent(void) pos_T *pos; pos_T paren; int amount; - char *that; // Set vi_lisp to use the vi-compatible method. int vi_lisp = (vim_strchr(p_cpo, CPO_LISP) != NULL); @@ -1217,7 +1195,7 @@ int get_lisp_indent(void) continue; } - for (that = get_cursor_line_ptr(); *that != NUL; that++) { + for (char *that = get_cursor_line_ptr(); *that != NUL; that++) { if (*that == ';') { while (*(that + 1) != NUL) { that++; @@ -1267,7 +1245,7 @@ int get_lisp_indent(void) curwin->w_cursor.col = pos->col; colnr_T col = pos->col; - that = get_cursor_line_ptr(); + char *that = get_cursor_line_ptr(); if (vi_lisp && (get_indent() == 0)) { amount = 2; diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 54651eb48d..44229c622b 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -597,7 +597,6 @@ static char *ins_compl_infercase_gettext(const char *str, int char_len, int comp int min_len, char **tofree) { bool has_lower = false; - bool was_letter = false; // Allocate wide character array for the completion and fill it. int *const wca = xmalloc((size_t)char_len * sizeof(*wca)); @@ -629,6 +628,7 @@ static char *ins_compl_infercase_gettext(const char *str, int char_len, int comp // Rule 2: No lower case, 2nd consecutive letter converted to // upper case. if (!has_lower) { + bool was_letter = false; const char *p = compl_orig_text; for (int i = 0; i < min_len; i++) { const int c = mb_ptr2char_adv(&p); diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index 49ec245359..f8475b3e22 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -1058,7 +1058,8 @@ char *vim_strsave_escape_ks(char *p) /// vim_strsave_escape_ks(). Works in-place. void vim_unescape_ks(char *p) { - uint8_t *s = (uint8_t *)p, *d = (uint8_t *)p; + uint8_t *s = (uint8_t *)p; + uint8_t *d = (uint8_t *)p; while (*s != NUL) { if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) { diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index fc2fedeaa1..4b7d2dab21 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -82,7 +82,8 @@ static int regex_match_line(lua_State *lstate) handle_T bufnr = (handle_T)luaL_checkinteger(lstate, 2); linenr_T rownr = (linenr_T)luaL_checkinteger(lstate, 3); - int start = 0, end = -1; + int start = 0; + int end = -1; if (narg >= 4) { start = (int)luaL_checkinteger(lstate, 4); } @@ -177,7 +178,8 @@ int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL } } - size_t codepoints = 0, codeunits = 0; + size_t codepoints = 0; + size_t codeunits = 0; mb_utflen(s1, (size_t)idx, &codepoints, &codeunits); lua_pushinteger(lstate, (lua_Integer)codepoints); diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index 16c3aa5e11..5285c1187d 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -74,7 +74,8 @@ static void get_linematch_results(lua_State *lstate, mmfile_t *ma, mmfile_t *mb, int *decisions = NULL; size_t decisions_length = linematch_nbuffers(diff_begin, diff_length, 2, &decisions, iwhite); - int lnuma = start_a, lnumb = start_b; + int lnuma = start_a; + int lnumb = start_b; int hunkstarta = lnuma; int hunkstartb = lnumb; diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index fa5e7dcbe2..958970bba1 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -146,7 +146,8 @@ static inline int marktree_getp_aux(const MTNode *x, MTKey k, bool *match) bool dummy_match; bool *m = match ? match : &dummy_match; - int begin = 0, end = x->n; + int begin = 0; + int end = x->n; if (x->n == 0) { *m = false; return -1; @@ -303,7 +304,8 @@ void marktree_put(MarkTree *b, MTKey key, int end_row, int end_col, bool end_rig |(uint16_t)(end_right ? MT_FLAG_RIGHT_GRAVITY : 0)); end_key.pos = (MTPos){ end_row, end_col }; marktree_put_key(b, end_key); - MarkTreeIter itr[1] = { 0 }, end_itr[1] = { 0 }; + MarkTreeIter itr[1] = { 0 }; + MarkTreeIter end_itr[1] = { 0 }; marktree_lookup(b, mt_lookup_key(key), itr); marktree_lookup(b, mt_lookup_key(end_key), end_itr); @@ -684,8 +686,10 @@ uint64_t marktree_del_itr(MarkTree *b, MarkTreeIter *itr, bool rev) static void intersect_merge(Intersection *restrict m, Intersection *restrict x, Intersection *restrict y) { - size_t xi = 0, yi = 0; - size_t xn = 0, yn = 0; + size_t xi = 0; + size_t yi = 0; + size_t xn = 0; + size_t yn = 0; while (xi < kv_size(*x) && yi < kv_size(*y)) { if (kv_A(*x, xi) == kv_A(*y, yi)) { // TODO(bfredl): kvi_pushp is actually quite complex, break out kvi_resize() to a function? @@ -717,8 +721,10 @@ static void intersect_merge(Intersection *restrict m, Intersection *restrict x, static void intersect_mov(Intersection *restrict x, Intersection *restrict y, Intersection *restrict w, Intersection *restrict d) { - size_t wi = 0, yi = 0; - size_t wn = 0, yn = 0; + size_t wi = 0; + size_t yi = 0; + size_t wn = 0; + size_t yn = 0; size_t xi = 0; while (wi < kv_size(*w) || xi < kv_size(*x)) { if (wi < kv_size(*w) && (xi >= kv_size(*x) || kv_A(*x, xi) >= kv_A(*w, wi))) { @@ -810,7 +816,8 @@ bool intersect_mov_test(const uint64_t *x, size_t nx, const uint64_t *y, size_t /// intersection: i = x & y static void intersect_common(Intersection *i, Intersection *x, Intersection *y) { - size_t xi = 0, yi = 0; + size_t xi = 0; + size_t yi = 0; while (xi < kv_size(*x) && yi < kv_size(*y)) { if (kv_A(*x, xi) == kv_A(*y, yi)) { kvi_push(*i, kv_A(*x, xi)); @@ -827,7 +834,8 @@ static void intersect_common(Intersection *i, Intersection *x, Intersection *y) // inplace union: x |= y static void intersect_add(Intersection *x, Intersection *y) { - size_t xi = 0, yi = 0; + size_t xi = 0; + size_t yi = 0; while (xi < kv_size(*x) && yi < kv_size(*y)) { if (kv_A(*x, xi) == kv_A(*y, yi)) { xi++; @@ -854,7 +862,8 @@ static void intersect_add(Intersection *x, Intersection *y) // inplace asymmetric difference: x &= ~y static void intersect_sub(Intersection *restrict x, Intersection *restrict y) { - size_t xi = 0, yi = 0; + size_t xi = 0; + size_t yi = 0; size_t xn = 0; while (xi < kv_size(*x) && yi < kv_size(*y)) { if (kv_A(*x, xi) == kv_A(*y, yi)) { @@ -898,7 +907,8 @@ static void bubble_up(MTNode *x) static MTNode *merge_node(MarkTree *b, MTNode *p, int i) { - MTNode *x = p->ptr[i], *y = p->ptr[i + 1]; + MTNode *x = p->ptr[i]; + MTNode *y = p->ptr[i + 1]; Intersection m; kvi_init(m); @@ -975,7 +985,8 @@ void kvi_move(Intersection *dest, Intersection *src) // key inside x, if x is the first leaf) static void pivot_right(MarkTree *b, MTPos p_pos, MTNode *p, const int i) { - MTNode *x = p->ptr[i], *y = p->ptr[i + 1]; + MTNode *x = p->ptr[i]; + MTNode *y = p->ptr[i + 1]; memmove(&y->key[1], y->key, (size_t)y->n * sizeof(MTKey)); if (y->level) { memmove(&y->ptr[1], y->ptr, ((size_t)y->n + 1) * sizeof(MTNode *)); @@ -1040,7 +1051,8 @@ static void pivot_right(MarkTree *b, MTPos p_pos, MTNode *p, const int i) static void pivot_left(MarkTree *b, MTPos p_pos, MTNode *p, int i) { - MTNode *x = p->ptr[i], *y = p->ptr[i + 1]; + MTNode *x = p->ptr[i]; + MTNode *y = p->ptr[i + 1]; // reverse from how we "always" do it. but pivot_left // is just the inverse of pivot_right, so reverse it literally. @@ -1603,7 +1615,8 @@ static void swap_keys(MarkTree *b, MarkTreeIter *itr1, MarkTreeIter *itr2, Damag static int damage_cmp(const void *s1, const void *s2) { - Damage *d1 = (Damage *)s1, *d2 = (Damage *)s2; + Damage *d1 = (Damage *)s1; + Damage *d2 = (Damage *)s2; assert(d1->id != d2->id); return d1->id > d2->id ? 1 : -1; } @@ -1619,7 +1632,8 @@ bool marktree_splice(MarkTree *b, int32_t start_line, int start_col, int old_ext bool same_line = old_extent.row == 0 && new_extent.row == 0; unrelative(start, &old_extent); unrelative(start, &new_extent); - MarkTreeIter itr[1] = { 0 }, enditr[1] = { 0 }; + MarkTreeIter itr[1] = { 0 }; + MarkTreeIter enditr[1] = { 0 }; MTPos oldbase[MT_MAX_DEPTH] = { 0 }; @@ -1824,7 +1838,8 @@ past_continue_same_node: void marktree_move_region(MarkTree *b, int start_row, colnr_T start_col, int extent_row, colnr_T extent_col, int new_row, colnr_T new_col) { - MTPos start = { start_row, start_col }, size = { extent_row, extent_col }; + MTPos start = { start_row, start_col }; + MTPos size = { extent_row, extent_col }; MTPos end = size; unrelative(start, &end); MarkTreeIter itr[1] = { 0 }; diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index f2883cc5c7..a992bf3cd8 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -1422,7 +1422,8 @@ int utf16_to_utf8(const wchar_t *utf16, int utf16len, char **utf8) void mb_utflen(const char *s, size_t len, size_t *codepoints, size_t *codeunits) FUNC_ATTR_NONNULL_ALL { - size_t count = 0, extra = 0; + size_t count = 0; + size_t extra = 0; size_t clen; for (size_t i = 0; i < len; i += clen) { clen = (size_t)utf_ptr2len_len(s + i, (int)(len - i)); diff --git a/src/nvim/memory.c b/src/nvim/memory.c index a0786391b5..feb13384be 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -286,7 +286,8 @@ void strchrsub(char *str, char c, char x) void memchrsub(void *data, char c, char x, size_t len) FUNC_ATTR_NONNULL_ALL { - char *p = data, *end = (char *)data + len; + char *p = data; + char *end = (char *)data + len; while ((p = memchr(p, c, (size_t)(end - p)))) { *p++ = x; } @@ -321,7 +322,8 @@ size_t memcnt(const void *data, char c, size_t len) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE { size_t cnt = 0; - const char *ptr = data, *end = ptr + len; + const char *ptr = data; + const char *end = ptr + len; while ((ptr = memchr(ptr, c, (size_t)(end - ptr))) != NULL) { cnt++; ptr++; // Skip the instance of c. diff --git a/src/nvim/move.c b/src/nvim/move.c index bbc3d792c0..891aa8f5ce 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1037,7 +1037,9 @@ void curs_columns(win_T *wp, int may_scroll) void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, int *ecolp, bool local) { - colnr_T scol = 0, ccol = 0, ecol = 0; + colnr_T scol = 0; + colnr_T ccol = 0; + colnr_T ecol = 0; int row = 0; colnr_T coloff = 0; bool visible_row = false; @@ -1129,7 +1131,9 @@ void f_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) pos.col = 0; } int row = 0; - int scol = 0, ccol = 0, ecol = 0; + int scol = 0; + int ccol = 0; + int ecol = 0; textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol, false); tv_dict_add_nr(dict, S_LEN("row"), row); diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 16aa46e97d..71c2c7930e 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -390,7 +390,8 @@ static void shift_block(oparg_T *oap, int amount) bd.start_vcol = cts.cts_vcol; clear_chartabsize_arg(&cts); - int tabs = 0, spaces = 0; + int tabs = 0; + int spaces = 0; // OK, now total=all the VWS reqd, and textstart points at the 1st // non-ws char in the block. if (!curbuf->b_p_et) { @@ -1891,7 +1892,8 @@ static int op_replace(oparg_T *oap, int c) size_t after_p_len = 0; int col = oldlen - bd.textcol - bd.textlen + 1; assert(col >= 0); - int newrows = 0, newcols = 0; + int newrows = 0; + int newcols = 0; if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { // strlen(newp) at this point int newp_len = bd.textcol + bd.startspaces; @@ -2040,11 +2042,9 @@ void op_tilde(oparg_T *oap) pos_T pos = oap->start; if (oap->motion_type == kMTBlockWise) { // Visual block mode for (; pos.lnum <= oap->end.lnum; pos.lnum++) { - int one_change; - block_prep(oap, &bd, pos.lnum, false); pos.col = bd.textcol; - one_change = swapchars(oap->op_type, &pos, bd.textlen); + int one_change = swapchars(oap->op_type, &pos, bd.textlen); did_change |= one_change; } if (did_change) { @@ -2636,7 +2636,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) break; case kMTCharWise: { - colnr_T startcol = 0, endcol = MAXCOL; + colnr_T startcol = 0; + colnr_T endcol = MAXCOL; int is_oneChar = false; colnr_T cs, ce; char *p = ml_get(lnum); @@ -2685,8 +2686,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) if (endcol == MAXCOL) { endcol = (colnr_T)strlen(p); } - if (startcol > endcol - || is_oneChar) { + if (startcol > endcol || is_oneChar) { bd.textlen = 0; } else { bd.textlen = endcol - startcol + oap->inclusive; diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 9ca8615467..41facb86eb 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -2815,7 +2815,8 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ if (c1 == 0 || char2cells(c1) > 1) { return e_invarg; } - int c2 = 0, c3 = 0; + int c2 = 0; + int c3 = 0; if (tab[i].cp == &lcs_chars.tab2) { if (*s == NUL) { return e_invarg; diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index e096749ce3..5b759e9d1e 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -415,7 +415,8 @@ static unsigned handle_mouse_event(const char **ptr, uint8_t *buf, unsigned bufs size_t input_enqueue_mouse(int code, uint8_t modifier, int grid, int row, int col) { modifier |= check_multiclick(code, grid, row, col); - uint8_t buf[7], *p = buf; + uint8_t buf[7]; + uint8_t *p = buf; if (modifier) { p[0] = K_SPECIAL; p[1] = KS_MODIFIER; diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index a0401f3a24..26e3171c5b 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -671,7 +671,8 @@ char *shell_argv_to_str(char **const argv) int os_call_shell(char *cmd, ShellOpts opts, char *extra_args) { DynamicBuffer input = DYNAMIC_BUFFER_INIT; - char *output = NULL, **output_ptr = NULL; + char *output = NULL; + char **output_ptr = NULL; int current_state = State; bool forward_output = true; @@ -1123,7 +1124,8 @@ static void out_data_ring(char *output, size_t size) static void out_data_append_to_screen(char *output, size_t *count, bool eof) FUNC_ATTR_NONNULL_ALL { - char *p = output, *end = output + *count; + char *p = output; + char *end = output + *count; while (p < end) { if (*p == '\n' || *p == '\r' || *p == TAB || *p == BELL) { msg_putchar_attr((uint8_t)(*p), 0); @@ -1236,7 +1238,8 @@ static size_t word_length(const char *str) /// before we finish writing. static void read_input(DynamicBuffer *buf) { - size_t written = 0, len = 0; + size_t written = 0; + size_t len = 0; linenr_T lnum = curbuf->b_op_start.lnum; char *lp = ml_get(lnum); diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 169909ea56..2a5777a774 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1358,9 +1358,13 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st assert(n <= SIZE_MAX - str_l); str_l += n; } else { - size_t min_field_width = 0, precision = 0; - int zero_padding = 0, precision_specified = 0, justify_left = 0; - int alternate_form = 0, force_sign = 0; + size_t min_field_width = 0; + size_t precision = 0; + int zero_padding = 0; + int precision_specified = 0; + int justify_left = 0; + int alternate_form = 0; + int force_sign = 0; // if both ' ' and '+' flags appear, ' ' flag should be ignored int space_for_positive = 1; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index c26e2a2259..da6bf134de 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -279,13 +279,12 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts) // - g:terminal_color_{NUM} // - the VTerm instance for (int i = 0; i < 16; i++) { - RgbValue color_val = -1; char var[64]; snprintf(var, sizeof(var), "terminal_color_%d", i); char *name = get_config_string(var); if (name) { int dummy; - color_val = name_to_color(name, &dummy); + RgbValue color_val = name_to_color(name, &dummy); xfree(name); if (color_val != -1) { @@ -390,7 +389,8 @@ void terminal_check_size(Terminal *term) int curwidth, curheight; vterm_get_size(term->vt, &curheight, &curwidth); - uint16_t width = 0, height = 0; + uint16_t width = 0; + uint16_t height = 0; // Check if there is a window that displays the terminal and find the maximum width and height. // Skip the autocommand window which isn't actually displayed. @@ -1430,7 +1430,9 @@ static void mouse_action(Terminal *term, int button, int row, int col, bool pres // terminal should lose focus static bool send_mouse_event(Terminal *term, int c) { - int row = mouse_row, col = mouse_col, grid = mouse_grid; + int row = mouse_row; + int col = mouse_col; + int grid = mouse_grid; win_T *mouse_win = mouse_find_win(&grid, &row, &col); if (mouse_win == NULL) { goto end; diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 496c192b95..ba4069ecf4 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1223,8 +1223,10 @@ void tui_grid_scroll(TUIData *tui, Integer g, Integer startrow, Integer endrow, Integer endcol, Integer rows, Integer cols FUNC_ATTR_UNUSED) { UGrid *grid = &tui->grid; - int top = (int)startrow, bot = (int)endrow - 1; - int left = (int)startcol, right = (int)endcol - 1; + int top = (int)startrow; + int bot = (int)endrow - 1; + int left = (int)startcol; + int right = (int)endcol - 1; bool fullwidth = left == 0 && right == tui->width - 1; tui->scroll_region_is_full_screen = fullwidth @@ -1565,7 +1567,8 @@ static void invalidate(TUIData *tui, int top, int bot, int left, int right) /// application (i.e., the host terminal). void tui_guess_size(TUIData *tui) { - int width = 0, height = 0; + int width = 0; + int height = 0; // 1 - try from a system call(ioctl/TIOCGWINSZ on unix) if (tui->out_isatty diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 1f94e4da63..48cf0489b7 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -198,7 +198,8 @@ void ui_refresh(void) return; } - int width = INT_MAX, height = INT_MAX; + int width = INT_MAX; + int height = INT_MAX; bool ext_widgets[kUIExtCount]; for (UIExtension i = 0; (int)i < kUIExtCount; i++) { ext_widgets[i] = true; diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index 5c9eeaabdf..fdd859ba29 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -203,7 +203,9 @@ void ui_client_event_grid_line(Array args) void ui_client_event_raw_line(GridLineEvent *g) { - int grid = g->args[0], row = g->args[1], startcol = g->args[2]; + int grid = g->args[0]; + int row = g->args[1]; + int startcol = g->args[2]; Integer endcol = startcol + g->coloff; Integer clearcol = endcol + g->clear_width; LineFlags lineflags = g->wrap ? kLineFlagWrap : 0; diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index c4078d6f63..baad8f3c29 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -305,7 +305,8 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag startcol = MAX(startcol, 0); // in case we start on the right half of a double-width char, we need to // check the left half. But skip it in output if it wasn't doublewidth. - int skipstart = 0, skipend = 0; + int skipstart = 0; + int skipend = 0; if (startcol > 0 && (flags & kLineFlagInvalid)) { startcol--; skipstart = 1; diff --git a/src/nvim/undo.c b/src/nvim/undo.c index fd3bb41de0..7c44f0de62 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -963,12 +963,11 @@ static u_header_T *unserialize_uhp(bufinfo_T *bi, const char *file_name) } // Unserialize all extmark undo information - ExtmarkUndoObject *extup; kv_init(uhp->uh_extmark); while ((c = undo_read_2c(bi)) == UF_ENTRY_MAGIC) { bool error = false; - extup = unserialize_extmark(bi, &error, file_name); + ExtmarkUndoObject *extup = unserialize_extmark(bi, &error, file_name); if (error) { kv_destroy(uhp->uh_extmark); xfree(extup); @@ -1553,7 +1552,9 @@ void u_read_undo(char *name, const uint8_t *hash, const char *orig_name FUNC_ATT // We have put all of the headers into a table. Now we iterate through the // table and swizzle each sequence number we have stored in uh_*_seq into // a pointer corresponding to the header with that sequence number. - int16_t old_idx = -1, new_idx = -1, cur_idx = -1; + int16_t old_idx = -1; + int16_t new_idx = -1; + int16_t cur_idx = -1; for (int i = 0; i < num_head; i++) { u_header_T *uhp = uhp_table[i]; if (uhp == NULL) { diff --git a/src/nvim/window.c b/src/nvim/window.c index fe9509548f..929a06350b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -759,7 +759,8 @@ void ui_ext_win_position(win_T *wp, bool validate) FloatConfig c = wp->w_float_config; if (!c.external) { ScreenGrid *grid = &default_grid; - Float row = c.row, col = c.col; + Float row = c.row; + Float col = c.col; if (c.relative == kFloatRelativeWindow) { Error dummy = ERROR_INIT; win_T *win = find_window_by_handle(c.window, &dummy); @@ -771,7 +772,8 @@ void ui_ext_win_position(win_T *wp, bool validate) ui_ext_win_position(win, validate); } grid = &win->w_grid; - int row_off = 0, col_off = 0; + int row_off = 0; + int col_off = 0; grid_adjust(&grid, &row_off, &col_off); row += row_off; col += col_off; @@ -5463,7 +5465,8 @@ void may_trigger_win_scrolled_resized(void) } int size_count = 0; - win_T *first_scroll_win = NULL, *first_size_win = NULL; + win_T *first_scroll_win = NULL; + win_T *first_size_win = NULL; int cwsr = check_window_scroll_resize(&size_count, &first_scroll_win, &first_size_win, NULL, NULL); @@ -7404,7 +7407,8 @@ void win_get_tabwin(handle_T id, int *tabnr, int *winnr) *tabnr = 0; *winnr = 0; - int tnum = 1, wnum = 1; + int tnum = 1; + int wnum = 1; FOR_ALL_TABS(tp) { FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp->handle == id) { diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 4efff3cfab..87069d5682 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -146,7 +146,9 @@ void win_config_float(win_T *wp, FloatConfig fconfig) fconfig.col += curwin->w_wcol; fconfig.window = curwin->handle; } else if (fconfig.relative == kFloatRelativeMouse) { - int row = mouse_row, col = mouse_col, grid = mouse_grid; + int row = mouse_row; + int col = mouse_col; + int grid = mouse_grid; win_T *mouse_win = mouse_find_win(&grid, &row, &col); if (mouse_win != NULL) { fconfig.relative = kFloatRelativeWindow; @@ -197,7 +199,8 @@ void win_config_float(win_T *wp, FloatConfig fconfig) row += parent->w_winrow; col += parent->w_wincol; ScreenGrid *grid = &parent->w_grid; - int row_off = 0, col_off = 0; + int row_off = 0; + int col_off = 0; grid_adjust(&grid, &row_off, &col_off); row += row_off; col += col_off; -- cgit From 428edcde7068ab44040e19b43343741e5ca59770 Mon Sep 17 00:00:00 2001 From: Amanda Graven Date: Tue, 28 Nov 2023 21:05:33 +0100 Subject: feat(api): add forward and back mouse buttons --- src/nvim/api/vim.c | 7 ++++++- src/nvim/os/input.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 70e6b840de..aed286165a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -345,7 +345,8 @@ Integer nvim_input(String keys) /// mouse input in a GUI. The deprecated pseudokey form /// ("") of |nvim_input()| has the same limitation. /// -/// @param button Mouse button: one of "left", "right", "middle", "wheel", "move". +/// @param button Mouse button: one of "left", "right", "middle", "wheel", "move", +/// "x1", "x2". /// @param action For ordinary buttons, one of "press", "drag", "release". /// For the wheel, one of "up", "down", "left", "right". Ignored for "move". /// @param modifier String of modifiers each represented by a single char. @@ -376,6 +377,10 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri code = KE_RIGHTMOUSE; } else if (strequal(button.data, "wheel")) { code = KE_MOUSEDOWN; + } else if (strequal(button.data, "x1")) { + code = KE_X1MOUSE; + } else if (strequal(button.data, "x2")) { + code = KE_X2MOUSE; } else if (strequal(button.data, "move")) { code = KE_MOUSEMOVE; } else { diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 5b759e9d1e..ed4267dcbb 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -311,7 +311,8 @@ static uint8_t check_multiclick(int code, int grid, int row, int col) } // For click events the number of clicks is updated. - if (code == KE_LEFTMOUSE || code == KE_RIGHTMOUSE || code == KE_MIDDLEMOUSE) { + if (code == KE_LEFTMOUSE || code == KE_RIGHTMOUSE || code == KE_MIDDLEMOUSE + || code == KE_X1MOUSE || code == KE_X2MOUSE) { uint64_t mouse_time = os_hrtime(); // time of current mouse click (ns) // compute the time elapsed since the previous mouse click and // convert p_mouse from ms to ns -- cgit From 1cf51a07a6bfb827efc36911cd018da3a3cb863b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 19 Dec 2023 08:01:05 +0800 Subject: fix(api): don't set coladd of mark (#26648) --- src/nvim/api/private/helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 70e63d0ad5..23ec815346 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -1044,7 +1044,7 @@ bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err) } } assert(INT32_MIN <= line && line <= INT32_MAX); - pos_T pos = { (linenr_T)line, (int)col, (int)col }; + pos_T pos = { (linenr_T)line, (int)col, 0 }; res = setmark_pos(*name.data, &pos, buf->handle, NULL); if (!res) { if (deleting) { -- cgit From 693aea0e9e1032aee85d56c1a3f33e0811dbdc18 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 19 Dec 2023 06:29:13 +0100 Subject: docs: small fixes (#26448) Co-authored-by: Gregory Anders <8965202+gpanders@users.noreply.github.com> Co-authored-by: Jordan Mandel --- src/nvim/options.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 0d5c24a793..cb25d481ec 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1441,11 +1441,11 @@ return { completion in the preview window. Only works in combination with "menu" or "menuone". - noinsert Do not insert any text for a match until the user selects + noinsert Do not insert any text for a match until the user selects a match from the menu. Only works in combination with "menu" or "menuone". No effect if "longest" is present. - noselect Do not select a match in the menu, force the user to + noselect Do not select a match in the menu, force the user to select one from the menu. Only works in combination with "menu" or "menuone". -- cgit From 7f6b775b45de5011ff1c44e63e57551566d80704 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 16 Dec 2023 22:14:28 +0100 Subject: refactor: use `bool` to represent boolean values --- src/nvim/arabic.c | 18 +++++++++--------- src/nvim/arglist.c | 4 ++-- src/nvim/autocmd.c | 6 +++--- src/nvim/buffer.c | 4 ++-- src/nvim/bufwrite.c | 16 ++++++++-------- src/nvim/change.c | 8 ++++---- src/nvim/cmdexpand.c | 8 ++++---- src/nvim/cmdhist.c | 2 +- src/nvim/cursor_shape.c | 2 +- src/nvim/diff.c | 16 ++++++++-------- src/nvim/drawline.c | 2 +- src/nvim/eval.c | 4 ++-- src/nvim/eval/funcs.c | 4 ++-- src/nvim/eval/userfunc.c | 8 ++++---- src/nvim/eval/vars.c | 2 +- src/nvim/ex_docmd.c | 2 +- src/nvim/ex_eval.c | 12 ++++++------ src/nvim/ex_getln.c | 11 ++++++----- src/nvim/ex_session.c | 12 ++++++------ src/nvim/file_search.c | 22 ++++++++++------------ src/nvim/fileio.c | 4 ++-- src/nvim/fold.c | 16 ++++++++-------- src/nvim/getchar.c | 12 ++++++------ src/nvim/grid.c | 2 +- src/nvim/highlight_group.c | 2 +- src/nvim/indent.c | 8 ++++---- src/nvim/main.c | 2 +- src/nvim/mapping.c | 4 ++-- src/nvim/memline.c | 4 ++-- src/nvim/menu.c | 10 +++++----- src/nvim/message.c | 13 +++++-------- src/nvim/move.c | 2 +- src/nvim/normal.c | 2 +- src/nvim/ops.c | 13 ++++++------- src/nvim/option.c | 8 ++++---- src/nvim/os/users.c | 2 +- src/nvim/path.c | 27 ++++++++++++--------------- src/nvim/popupmenu.c | 2 +- src/nvim/quickfix.c | 4 ++-- src/nvim/runtime.c | 2 +- src/nvim/sign.c | 2 +- src/nvim/statusline.c | 8 ++++---- src/nvim/strings.c | 2 +- src/nvim/syntax.c | 13 +++++-------- src/nvim/tag.c | 20 ++++++++++---------- src/nvim/textformat.c | 2 +- src/nvim/textobject.c | 4 ++-- 47 files changed, 171 insertions(+), 182 deletions(-) (limited to 'src') diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c index f575bf30b8..665e61c277 100644 --- a/src/nvim/arabic.c +++ b/src/nvim/arabic.c @@ -270,22 +270,22 @@ bool arabic_combine(int one, int two) return false; } -/// A_is_iso returns true if 'c' is an Arabic ISO-8859-6 character +/// @return true if 'c' is an Arabic ISO-8859-6 character /// (alphabet/number/punctuation) -static int A_is_iso(int c) +static bool A_is_iso(int c) { return find_achar(c) != NULL; } -/// A_is_ok returns true if 'c' is an Arabic 10646 (8859-6 or Form-B) -static int A_is_ok(int c) +/// @return true if 'c' is an Arabic 10646 (8859-6 or Form-B) +static bool A_is_ok(int c) { return (A_is_iso(c) || c == a_BYTE_ORDER_MARK); } -/// A_is_valid returns true if 'c' is an Arabic 10646 (8859-6 or Form-B) -/// with some exceptions/exclusions -static int A_is_valid(int c) +/// @return true if 'c' is an Arabic 10646 (8859-6 or Form-B) +/// with some exceptions/exclusions +static bool A_is_valid(int c) { return (A_is_ok(c) && c != a_HAMZA); } @@ -304,8 +304,8 @@ int arabic_shape(int c, int *c1p, int prev_c, int prev_c1, int next_c) } int curr_c; - int curr_laa = arabic_combine(c, *c1p); - int prev_laa = arabic_combine(prev_c, prev_c1); + bool curr_laa = arabic_combine(c, *c1p); + bool prev_laa = arabic_combine(prev_c, prev_c1); if (curr_laa) { if (A_is_valid(prev_c) && can_join(prev_c, a_LAM) && !prev_laa) { diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index 8bc8edb572..a2f3aa11ca 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -280,7 +280,7 @@ static char *do_one_arg(char *str) /// Separate the arguments in "str" and return a list of pointers in the /// growarray "gap". -static void get_arglist(garray_T *gap, char *str, int escaped) +static void get_arglist(garray_T *gap, char *str, bool escaped) { ga_init(gap, (int)sizeof(char *), 20); while (*str != NUL) { @@ -426,7 +426,7 @@ static int do_arglist(char *str, int what, int after, bool will_edit) garray_T new_ga; int exp_count; char **exp_files; - int arg_escaped = true; + bool arg_escaped = true; if (check_arglist_locked() == FAIL) { return FAIL; diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index bfcf566fe3..9605e3b4db 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -913,7 +913,7 @@ int do_autocmd_event(event_T event, const char *pat, bool once, int nested, char int patlen = (int)aucmd_pattern_length(pat); while (patlen) { // detect special buffer-local patterns - int is_buflocal = aupat_is_buflocal(pat, patlen); + bool is_buflocal = aupat_is_buflocal(pat, patlen); if (is_buflocal) { const int buflocal_nr = aupat_get_buflocal_nr(pat, patlen); @@ -977,7 +977,7 @@ int autocmd_register(int64_t id, event_T event, const char *pat, int patlen, int const int findgroup = group == AUGROUP_ALL ? current_augroup : group; // detect special buffer-local patterns - const int is_buflocal = aupat_is_buflocal(pat, patlen); + const bool is_buflocal = aupat_is_buflocal(pat, patlen); int buflocal_nr = 0; char buflocal_pat[BUFLOCAL_PAT_LEN]; // for "" @@ -1568,7 +1568,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force static int nesting = 0; char *save_cmdarg; varnumber_T save_cmdbang; - static int filechangeshell_busy = false; + static bool filechangeshell_busy = false; proftime_T wait_time; bool did_save_redobuff = false; save_redo_T save_redo; diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 75c6545c1d..7660093fc2 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -201,13 +201,13 @@ bool buf_ensure_loaded(buf_T *buf) /// @param flags_arg extra flags for readfile() /// /// @return FAIL for failure, OK otherwise. -int open_buffer(int read_stdin, exarg_T *eap, int flags_arg) +int open_buffer(bool read_stdin, exarg_T *eap, int flags_arg) { int flags = flags_arg; int retval = OK; bufref_T old_curbuf; OptInt old_tw = curbuf->b_p_tw; - int read_fifo = false; + bool read_fifo = false; bool silent = shortmess(SHM_FILEINFO); // The 'readonly' flag is only set when BF_NEVERLOADED is being reset. diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index f8df273375..67e5fb3b6f 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -799,7 +799,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o char *backup_ext = *p_bex == NUL ? ".bak" : p_bex; if (*backup_copyp) { - int some_error = false; + bool some_error = false; // Try to make the backup in each directory in the 'bdir' option. // @@ -1059,14 +1059,14 @@ nobackup: /// /// @return FAIL for failure, OK otherwise int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T end, exarg_T *eap, - int append, int forceit, int reset_changed, int filtering) + bool append, bool forceit, bool reset_changed, bool filtering) { int retval = OK; int msg_save = msg_scroll; - int prev_got_int = got_int; + bool prev_got_int = got_int; // writing everything - int whole = (start == 1 && end == buf->b_ml.ml_line_count); - int write_undo_file = false; + bool whole = (start == 1 && end == buf->b_ml.ml_line_count); + bool write_undo_file = false; context_sha256_T sha_ctx; unsigned bkc = get_bkc_value(buf); @@ -1245,7 +1245,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en } #if defined(UNIX) - int made_writable = false; // 'w' bit has been set + bool made_writable = false; // 'w' bit has been set // When using ":w!" and the file was read-only: make it writable if (forceit && perm >= 0 && !(perm & 0200) @@ -1352,7 +1352,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en } } - int notconverted = false; + bool notconverted = false; if (converted && wb_flags == 0 && write_info.bw_iconv_fd == (iconv_t)-1 @@ -1364,7 +1364,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en notconverted = true; } - int no_eol = false; // no end-of-line written + bool no_eol = false; // no end-of-line written int nchars; linenr_T lnum; int fileformat; diff --git a/src/nvim/change.c b/src/nvim/change.c index 622eb3b9a5..99698f2e5d 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -1322,7 +1322,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) char *comment_end = NULL; // where lead_end has been found int extra_space = false; // append extra space int current_flag; - int require_blank = false; // requires blank after middle + bool require_blank = false; // requires blank after middle char *p2; // If the comment leader has the start, middle or end flag, it may not @@ -1979,7 +1979,7 @@ void del_lines(linenr_T nlines, bool undo) int get_leader_len(char *line, char **flags, bool backward, bool include_space) { int j; - int got_com = false; + bool got_com = false; char part_buf[COM_MAX_LEN]; // buffer for one option part char *string; // pointer to comment string int middle_match_len = 0; @@ -1994,7 +1994,7 @@ int get_leader_len(char *line, char **flags, bool backward, bool include_space) // Repeat to match several nested comment strings. while (line[i] != NUL) { // scan through the 'comments' option for a match - int found_one = false; + bool found_one = false; for (char *list = curbuf->b_p_com; *list;) { // Get one option part into part_buf[]. Advance "list" to next // one. Put "string" at start of string. @@ -2129,7 +2129,7 @@ int get_last_leader_offset(char *line, char **flags) int i = (int)strlen(line); while (--i >= lower_check_bound) { // scan through the 'comments' option for a match - int found_one = false; + bool found_one = false; for (char *list = curbuf->b_p_com; *list;) { char *flags_save = list; diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 523145af1b..31b385c466 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -841,7 +841,7 @@ static char *find_longest_match(expand_T *xp, int options) char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) { char *ss = NULL; - int orig_saved = false; + bool orig_saved = false; // first handle the case of using an old match if (mode == WILD_NEXT || mode == WILD_PREV @@ -3311,7 +3311,7 @@ static int wildmenu_process_key_menunames(CmdlineInfo *cclp, int key, expand_T * } else if (key == K_UP) { // Hitting : Remove one submenu name in front of the // cursor - int found = false; + bool found = false; int j = (int)(xp->xp_pattern - cclp->cmdbuff); int i = 0; @@ -3367,7 +3367,7 @@ static int wildmenu_process_key_filenames(CmdlineInfo *cclp, int key, expand_T * KeyTyped = true; // in case the key was mapped } else if (strncmp(xp->xp_pattern, upseg + 1, 3) == 0 && key == K_DOWN) { // If in a direct ancestor, strip off one ../ to go down - int found = false; + bool found = false; int j = cclp->cmdpos; int i = (int)(xp->xp_pattern - cclp->cmdbuff); @@ -3388,7 +3388,7 @@ static int wildmenu_process_key_filenames(CmdlineInfo *cclp, int key, expand_T * } } else if (key == K_UP) { // go up a directory - int found = false; + bool found = false; int j = cclp->cmdpos - 1; int i = (int)(xp->xp_pattern - cclp->cmdbuff); diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index 9396fdac7f..51a73dec10 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -374,7 +374,7 @@ static int calc_hist_idx(int histype, int num) histentry_T *hist = history[histype]; if (num > 0) { - int wrapped = false; + bool wrapped = false; while (hist[i].hisnum > num) { if (--i < 0) { if (wrapped) { diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index fe07c33df5..64cf1ea263 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -110,7 +110,7 @@ const char *parse_shape_opt(int what) int all_idx; int len; int i; - int found_ve = false; // found "ve" flag + bool found_ve = false; // found "ve" flag // First round: check for errors; second round: do it for real. for (int round = 1; round <= 2; round++) { diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 483182dc25..765cbdadd2 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -59,7 +59,7 @@ #include "nvim/window.h" #include "xdiff/xdiff.h" -static int diff_busy = false; // using diff structs, don't change them +static bool diff_busy = false; // using diff structs, don't change them static bool diff_need_update = false; // ex_diffupdate needs to be called // Flags obtained from the 'diffopt' option @@ -384,7 +384,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T } dp->df_lnum[idx] += amount_after; } else { - int check_unchanged = false; + bool check_unchanged = false; // 2. 3. 4. 5.: inserted/deleted lines touching this diff. if (deleted > 0) { @@ -1003,7 +1003,7 @@ theend: static int check_external_diff(diffio_T *diffio) { // May try twice, first with "-a" and then without. - int io_error = false; + bool io_error = false; TriState ok = kFalse; while (true) { ok = kFalse; @@ -1472,7 +1472,7 @@ void diff_win_options(win_T *wp, int addbuf) /// @param eap void ex_diffoff(exarg_T *eap) { - int diffwin = false; + bool diffwin = false; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (eap->forceit ? wp->w_p_diff : (wp == curwin)) { @@ -2155,12 +2155,12 @@ int diff_check_with_linestatus(win_T *wp, linenr_T lnum, int *linestatus) } if (lnum < dp->df_lnum[idx] + dp->df_count[idx]) { - int zero = false; + bool zero = false; // Changed or inserted line. If the other buffers have a count of // zero, the lines were inserted. If the other buffers have the same // count, check if the lines are identical. - int cmp = false; + bool cmp = false; for (int i = 0; i < DB_COUNT; i++) { if ((i != idx) && (curtab->tp_diffbuf[i] != NULL)) { @@ -2195,7 +2195,7 @@ int diff_check_with_linestatus(win_T *wp, linenr_T lnum, int *linestatus) // the difference. Can't remove the entry here, we might be halfway // through updating the window. Just report the text as unchanged. // Other windows might still show the change though. - if (zero == false) { + if (!zero) { return 0; } return -2; @@ -2845,7 +2845,7 @@ void ex_diffgetput(exarg_T *eap) } if (*eap->arg == NUL) { - int found_not_ma = false; + bool found_not_ma = false; // No argument: Find the other buffer in the list of diff buffers. for (idx_other = 0; idx_other < DB_COUNT; idx_other++) { if ((curtab->tp_diffbuf[idx_other] != curbuf) diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 77bd05eb55..ee1cd0a3ce 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -1076,7 +1076,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl int prev_syntax_id = 0; int conceal_attr = win_hl_attr(wp, HLF_CONCEAL); bool is_concealing = false; - int did_wcol = false; + bool did_wcol = false; int old_boguscols = 0; #define VCOL_HLC (wlv.vcol - wlv.vcol_off) #define FIX_FOR_BOGUSCOLS \ diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7d869881e8..21bb325e37 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -564,7 +564,7 @@ static char *redir_varname = NULL; /// @param append append to an existing variable /// /// @return OK if successfully completed the setup. FAIL otherwise. -int var_redir_start(char *name, int append) +int var_redir_start(char *name, bool append) { // Catch a bad name early. if (!eval_isnamec1(*name)) { @@ -765,7 +765,7 @@ void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip) /// @param skip only parse, don't execute /// /// @return true or false. -int eval_to_bool(char *arg, bool *error, exarg_T *eap, int skip) +bool eval_to_bool(char *arg, bool *error, exarg_T *eap, int skip) { typval_T tv; bool retval = false; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 81ae208560..f13235c3e9 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -305,7 +305,7 @@ int call_internal_method(const char *const fname, const int argcount, typval_T * } /// @return true for a non-zero Number and a non-empty String. -static int non_zero_arg(typval_T *argvars) +static bool non_zero_arg(typval_T *argvars) { return ((argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number != 0) @@ -2443,7 +2443,7 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos, bool : (varnumber_T)0)); tv_list_append_number(l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0); if (getcurpos) { - const int save_set_curswant = curwin->w_set_curswant; + const bool save_set_curswant = curwin->w_set_curswant; const colnr_T save_curswant = curwin->w_curswant; const colnr_T save_virtcol = curwin->w_virtcol; diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index cce02e6daf..5e943711d1 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -928,7 +928,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett int tv_to_free_len = 0; proftime_T wait_start; proftime_T call_start; - int started_profiling = false; + bool started_profiling = false; bool did_save_redo = false; save_redo_T save_redo; @@ -3035,7 +3035,7 @@ static inline bool fc_referenced(const funccall_T *const fc) /// @return true if items in "fc" do not have "copyID". That means they are not /// referenced from anywhere that is in use. -static int can_free_funccal(funccall_T *fc, int copyID) +static bool can_free_funccal(funccall_T *fc, int copyID) { return fc->fc_l_varlist.lv_copyID != copyID && fc->fc_l_vars.dv_copyID != copyID @@ -3048,7 +3048,7 @@ void ex_return(exarg_T *eap) { char *arg = eap->arg; typval_T rettv; - int returning = false; + bool returning = false; if (current_funccal == NULL) { emsg(_("E133: :return not inside a function")); @@ -3395,7 +3395,7 @@ end: /// /// @return true when the return can be carried out, /// false when the return gets pending. -int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) +bool do_return(exarg_T *eap, bool reanimate, bool is_cmd, void *rettv) { cstack_T *const cstack = eap->cstack; diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 9897ca77f1..de2fddb083 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -616,7 +616,7 @@ static void list_tab_vars(int *first) /// List variables in "arg". static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) { - int error = false; + bool error = false; int len; const char *name; const char *name_start; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index d8e2c54efa..c268f47323 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6212,7 +6212,7 @@ static void ex_redir(exarg_T *eap) semsg(_(e_invarg2), eap->arg); } } else if (*arg == '=' && arg[1] == '>') { - int append; + bool append; // redirect to a variable close_redir(); diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index bc4cb634e8..c239e8a9ea 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -92,7 +92,7 @@ static void discard_pending_return(typval_T *p) // expression evaluation is done without producing any error messages, but all // error messages on parsing errors during the expression evaluation are given // (even if a try conditional is active). -static int cause_abort = false; +static bool cause_abort = false; /// @return true when immediately aborting on error, or when an interrupt /// occurred or an exception was thrown but not caught. @@ -844,7 +844,7 @@ void ex_if(exarg_T *eap) int skip = CHECK_SKIP; bool error; - int result = eval_to_bool(eap->arg, &error, eap, skip); + bool result = eval_to_bool(eap->arg, &error, eap, skip); if (!skip && !error) { if (result) { @@ -971,7 +971,7 @@ void ex_while(exarg_T *eap) if (cstack->cs_idx == CSTACK_LEN - 1) { eap->errmsg = _("E585: :while/:for nesting too deep"); } else { - int result; + bool result; // The loop flag is set when we have jumped back from the matching // ":endwhile" or ":endfor". When not set, need to initialise this // cstack entry. @@ -1183,7 +1183,7 @@ void ex_throw(exarg_T *eap) /// used for rethrowing an uncaught exception. void do_throw(cstack_T *cstack) { - int inactivate_try = false; + bool inactivate_try = false; // Cleanup and deactivate up to the next surrounding try conditional that // is not in its finally clause. Normally, do not deactivate the try @@ -1861,7 +1861,7 @@ void leave_cleanup(cleanup_T *csp) int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive) { int idx; - int stop = false; + bool stop = false; for (idx = cstack->cs_idx; idx >= 0; idx--) { if (cstack->cs_flags[idx] & CSF_TRY) { @@ -1998,7 +1998,7 @@ void ex_endfunction(exarg_T *eap) } /// @return true if the string "p" looks like a ":while" or ":for" command. -int has_loop_cmd(char *p) +bool has_loop_cmd(char *p) { // skip modifiers, white space and ':' while (true) { diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index afaf0a6e2b..974115d803 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -109,7 +109,7 @@ typedef struct command_line_state { int count; int indent; int c; - int gotesc; // true when just typed + bool gotesc; // true when just typed int do_abbr; // when true check for abbr. char *lookfor; // string to match int hiscnt; // current history line in use @@ -584,7 +584,8 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s) return OK; } -static void finish_incsearch_highlighting(int gotesc, incsearch_state_T *s, bool call_update_screen) +static void finish_incsearch_highlighting(bool gotesc, incsearch_state_T *s, + bool call_update_screen) { if (!s->did_incsearch) { return; @@ -840,7 +841,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear // error printed below, to avoid redraw issues tl_ret = try_leave(&tstate, &err); if (tv_dict_get_number(dict, "abort") != 0) { - s->gotesc = 1; + s->gotesc = true; } restore_v_event(dict, &save_v_event); } @@ -4206,7 +4207,7 @@ int get_cmdline_firstc(void) int get_list_range(char **str, int *num1, int *num2) { int len; - int first = false; + bool first = false; varnumber_T num; *str = skipwhite((*str)); @@ -4280,7 +4281,7 @@ static int open_cmdwin(void) int save_restart_edit = restart_edit; int save_State = State; bool save_exmode = exmode_active; - int save_cmdmsg_rl = cmdmsg_rl; + bool save_cmdmsg_rl = cmdmsg_rl; // Can't do this when text or buffer is locked. // Can't do this recursively. Can't do it when typing a password. diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 45f05e10f2..6ae401a58c 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -59,7 +59,7 @@ static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces) return r >= 0; } -static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) +static int ses_winsizes(FILE *fd, bool restore_size, win_T *tab_firstwin) { if (restore_size && (ssop_flags & SSOP_WINSIZE)) { int n = 0; @@ -314,7 +314,7 @@ static int ses_put_fname(FILE *fd, char *name, unsigned *flagp) static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx) { int f; - int did_next = false; + bool did_next = false; // Always restore cursor position for ":mksession". For ":mkview" only // when 'viewoptions' contains "cursor". @@ -528,8 +528,8 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr /// @return FAIL on error, OK otherwise. static int makeopens(FILE *fd, char *dirnow) { - int only_save_windows = true; - int restore_size = true; + bool only_save_windows = true; + bool restore_size = true; win_T *edited_win = NULL; win_T *tab_firstwin; frame_T *tab_topframe; @@ -627,7 +627,7 @@ static int makeopens(FILE *fd, char *dirnow) } } - int restore_stal = false; + bool restore_stal = false; // When there are two or more tabpages and 'showtabline' is 1 the tabline // will be displayed when creating the next tab. That resizes the windows // in the first tab, which may cause problems. Set 'showtabline' to 2 @@ -886,7 +886,7 @@ void ex_loadview(exarg_T *eap) /// - SSOP_SLASH: filenames are written with "/" slash void ex_mkrc(exarg_T *eap) { - int view_session = false; // :mkview, :mksession + bool view_session = false; // :mkview, :mksession int using_vdir = false; // using 'viewdir'? char *viewFile = NULL; diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 460cd48fc5..acbcaa16c2 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -882,7 +882,7 @@ char *vim_findfile(void *search_ctx_arg) // is the last starting directory in the stop list? if (ff_path_in_stoplist(search_ctx->ffsc_start_dir, (int)(path_end - search_ctx->ffsc_start_dir), - search_ctx->ffsc_stopdirs_v) == true) { + search_ctx->ffsc_stopdirs_v)) { break; } @@ -1221,7 +1221,7 @@ static void ff_clear(ff_search_ctx_T *search_ctx) /// check if the given path is in the stopdirs /// /// @return true if yes else false -static int ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v) +static bool ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v) { int i = 0; @@ -1338,11 +1338,9 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch { ff_search_ctx_T **search_ctx = (ff_search_ctx_T **)search_ctx_arg; static char *dir; - static int did_findfile_init = false; - char save_char; + static bool did_findfile_init = false; char *file_name = NULL; char *buf = NULL; - int rel_to_curdir; if (rel_fname != NULL && path_with_url(rel_fname)) { // Do not attempt to search "relative" to a URL. #6009 @@ -1355,7 +1353,7 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch } // copy file name into NameBuff, expanding environment variables - save_char = ptr[len]; + char save_char = ptr[len]; ptr[len] = NUL; expand_env_esc(ptr, NameBuff, MAXPATHL, false, true, NULL); ptr[len] = save_char; @@ -1372,12 +1370,12 @@ char *find_file_in_path_option(char *ptr, size_t len, int options, int first, ch } } - rel_to_curdir = ((*file_to_find)[0] == '.' - && ((*file_to_find)[1] == NUL - || vim_ispathsep((*file_to_find)[1]) - || ((*file_to_find)[1] == '.' - && ((*file_to_find)[2] == NUL - || vim_ispathsep((*file_to_find)[2]))))); + bool rel_to_curdir = ((*file_to_find)[0] == '.' + && ((*file_to_find)[1] == NUL + || vim_ispathsep((*file_to_find)[1]) + || ((*file_to_find)[1] == '.' + && ((*file_to_find)[2] == NUL + || vim_ispathsep((*file_to_find)[2]))))); if (vim_isAbsName(*file_to_find) // "..", "../path", "." and "./path": don't use the path_option || rel_to_curdir diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 0e2959835b..066a150f5a 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -180,7 +180,7 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip, off_T filesize = 0; bool skip_read = false; context_sha256_T sha_ctx; - int read_undo_file = false; + bool read_undo_file = false; int split = 0; // number of split lines linenr_T linecnt; bool error = false; // errors encountered @@ -2754,7 +2754,7 @@ int vim_rename(const char *from, const char *to) return 0; } -static int already_warned = false; +static bool already_warned = false; /// Check if any not hidden buffer has been changed. /// Postpone the check if there are characters in the stuff buffer, a global diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 9e90ab9439..a268070dec 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -319,42 +319,42 @@ foldinfo_T fold_info(win_T *win, linenr_T lnum) // foldmethodIsManual() {{{2 /// @return true if 'foldmethod' is "manual" -int foldmethodIsManual(win_T *wp) +bool foldmethodIsManual(win_T *wp) { return wp->w_p_fdm[3] == 'u'; } // foldmethodIsIndent() {{{2 /// @return true if 'foldmethod' is "indent" -int foldmethodIsIndent(win_T *wp) +bool foldmethodIsIndent(win_T *wp) { return wp->w_p_fdm[0] == 'i'; } // foldmethodIsExpr() {{{2 /// @return true if 'foldmethod' is "expr" -int foldmethodIsExpr(win_T *wp) +bool foldmethodIsExpr(win_T *wp) { return wp->w_p_fdm[1] == 'x'; } // foldmethodIsMarker() {{{2 /// @return true if 'foldmethod' is "marker" -int foldmethodIsMarker(win_T *wp) +bool foldmethodIsMarker(win_T *wp) { return wp->w_p_fdm[2] == 'r'; } // foldmethodIsSyntax() {{{2 /// @return true if 'foldmethod' is "syntax" -int foldmethodIsSyntax(win_T *wp) +bool foldmethodIsSyntax(win_T *wp) { return wp->w_p_fdm[0] == 's'; } // foldmethodIsDiff() {{{2 /// @return true if 'foldmethod' is "diff" -int foldmethodIsDiff(win_T *wp) +bool foldmethodIsDiff(win_T *wp) { return wp->w_p_fdm[0] == 'd'; } @@ -536,8 +536,8 @@ int foldManualAllowed(bool create) /// window. void foldCreate(win_T *wp, pos_T start, pos_T end) { - int use_level = false; - int closed = false; + bool use_level = false; + bool closed = false; int level = 0; pos_T start_rel = start; pos_T end_rel = end; diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 0ccf1823f8..305b18fc28 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -91,7 +91,7 @@ static int typeahead_char = 0; ///< typeahead char that's not flushed /// When block_redo is true the redo buffer will not be changed. /// Used by edit() to repeat insertions. -static int block_redo = false; +static bool block_redo = false; static int KeyNoremap = 0; ///< remapping flags @@ -375,16 +375,16 @@ static void start_stuff(void) } } -/// Return true if the stuff buffer is empty. -int stuff_empty(void) +/// @return true if the stuff buffer is empty. +bool stuff_empty(void) FUNC_ATTR_PURE { return (readbuf1.bh_first.b_next == NULL && readbuf2.bh_first.b_next == NULL); } -/// Return true if readbuf1 is empty. There may still be redo characters in -/// redbuf2. -int readbuf1_empty(void) +/// @return true if readbuf1 is empty. There may still be redo characters in +/// redbuf2. +bool readbuf1_empty(void) FUNC_ATTR_PURE { return (readbuf1.bh_first.b_next == NULL); diff --git a/src/nvim/grid.c b/src/nvim/grid.c index 9830f25dcb..37e538ea16 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -919,7 +919,7 @@ void win_grid_alloc(win_T *wp) wp->w_lines = xcalloc((size_t)rows + 1, sizeof(wline_T)); } - int was_resized = false; + bool was_resized = false; if (want_allocation && (!has_allocation || grid_allocated->rows != total_rows || grid_allocated->cols != total_cols)) { diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 7c64571c11..683ad0c8a3 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -670,7 +670,7 @@ void syn_init_cmdline_highlight(bool reset, bool init) /// @param reset clear groups first void init_highlight(bool both, bool reset) { - static int had_both = false; + static bool had_both = false; // Try finding the color scheme file. Used when a color file was loaded // and 'background' or 't_Co' is changed. diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 61422561e0..adb609358d 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -434,7 +434,7 @@ int get_indent_str_vtab(const char *ptr, OptInt ts, colnr_T *vts, bool list) /// @param size measured in spaces /// /// @return true if the line was changed. -int set_indent(int size, int flags) +bool set_indent(int size, int flags) { char *newline; char *oldline; @@ -442,7 +442,7 @@ int set_indent(int size, int flags) int doit = false; int ind_done = 0; // Measured in spaces. int tab_pad; - int retval = false; + bool retval = false; // Number of initial whitespace chars when 'et' and 'pi' are both set. int orig_char_len = -1; @@ -1094,14 +1094,14 @@ void ex_retab(exarg_T *eap) /// Get indent level from 'indentexpr'. int get_expr_indent(void) { - int use_sandbox = was_set_insecurely(curwin, kOptIndentexpr, OPT_LOCAL); + bool use_sandbox = was_set_insecurely(curwin, kOptIndentexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Save and restore cursor position and curswant, in case it was changed // * via :normal commands. pos_T save_pos = curwin->w_cursor; colnr_T save_curswant = curwin->w_curswant; - int save_set_curswant = curwin->w_set_curswant; + bool save_set_curswant = curwin->w_set_curswant; set_vim_var_nr(VV_LNUM, (varnumber_T)curwin->w_cursor.lnum); if (use_sandbox) { diff --git a/src/nvim/main.c b/src/nvim/main.c index 521d67a638..bf0b8d33b2 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1680,7 +1680,7 @@ static void create_windows(mparm_T *parmp) // Don't execute Win/Buf Enter/Leave autocommands here autocmd_no_enter++; autocmd_no_leave++; - int dorewind = true; + bool dorewind = true; while (done++ < 1000) { if (dorewind) { if (parmp->window_layout == WIN_TABS) { diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 345ec45152..cb50050344 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -1121,7 +1121,7 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo MAPMODE(mode, modechars, 'c', MODE_CMDLINE); #undef MAPMODE - int retval = map_to_exists_mode(rhs, mode, abbr); + bool retval = map_to_exists_mode(rhs, mode, abbr); xfree(buf); return retval; @@ -1137,7 +1137,7 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo /// @param[in] abbr true if checking abbreviations in place of mappings. /// /// @return true if there is at least one mapping with given parameters. -int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr) +bool map_to_exists_mode(const char *const rhs, const int mode, const bool abbr) { bool exp_buffer = false; diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 38ac3b7bcf..25c2de89e0 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -3347,7 +3347,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ if (!recoverymode && buf_fname != NULL && !buf->b_help && !(buf->b_flags & BF_DUMMY)) { int fd; ZeroBlock b0; - int differ = false; + bool differ = false; // Try to read block 0 from the swapfile to get the original file name (and inode number). fd = os_open(fname, O_RDONLY, 0); @@ -3386,7 +3386,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_ // Show the ATTENTION message when: // - there is an old swapfile for the current file // - the buffer was not recovered - if (differ == false && !(curbuf->b_flags & BF_RECOVERED) + if (!differ && !(curbuf->b_flags & BF_RECOVERED) && vim_strchr(p_shm, SHM_ATTENTION) == NULL) { sea_choice_T choice = SEA_CHOICE_NONE; diff --git a/src/nvim/menu.c b/src/nvim/menu.c index bc850d8961..68a8c9f873 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -968,7 +968,7 @@ char *get_menu_name(expand_T *xp, int idx) { static vimmenu_T *menu = NULL; char *str; - static int should_advance = false; + static bool should_advance = false; if (idx == 0) { // first call: start at first item menu = expand_menu; @@ -1334,9 +1334,9 @@ bool menu_is_toolbar(const char *const name) return strncmp(name, "ToolBar", 7) == 0; } -/// Return true if the name is a menu separator identifier: Starts and ends -/// with '-' -int menu_is_separator(char *name) +/// @return true if the name is a menu separator identifier: Starts and ends +/// with '-' +bool menu_is_separator(char *name) { return name[0] == '-' && name[strlen(name) - 1] == '-'; } @@ -1344,7 +1344,7 @@ int menu_is_separator(char *name) /// True if a popup menu or starts with \ref MNU_HIDDEN_CHAR /// /// @return true if the menu is hidden -static int menu_is_hidden(char *name) +static bool menu_is_hidden(char *name) { return (name[0] == MNU_HIDDEN_CHAR) || (menu_is_popup(name) && name[5] != NUL); diff --git a/src/nvim/message.c b/src/nvim/message.c index 6aaa00cee9..38952d2cf6 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -88,7 +88,7 @@ MessageHistoryEntry *last_msg_hist = NULL; static int msg_hist_len = 0; static FILE *verbose_fd = NULL; -static int verbose_did_open = false; +static bool verbose_did_open = false; bool keep_msg_more = false; // keep_msg was set by msgmore() @@ -2549,11 +2549,9 @@ void clear_sb_text(int all) /// "g<" command. void show_sb_text(void) { - msgchunk_T *mp; - // Only show something if there is more than one line, otherwise it looks // weird, typing a command without output results in one line. - mp = msg_sb_start(last_msgchunk); + msgchunk_T *mp = msg_sb_start(last_msgchunk); if (mp == NULL || mp->sb_prev == NULL) { vim_beep(BO_MESS); } else { @@ -2663,13 +2661,13 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) /// otherwise it's NUL. /// /// @return true when jumping ahead to "confirm_msg_tail". -static int do_more_prompt(int typed_char) +static bool do_more_prompt(int typed_char) { static bool entered = false; int used_typed_char = typed_char; int oldState = State; int c; - int retval = false; + bool retval = false; bool to_redraw = false; msgchunk_T *mp_last = NULL; msgchunk_T *mp; @@ -3395,7 +3393,6 @@ int do_dialog(int type, const char *title, const char *message, const char *butt const char *textfield, int ex_cmd) { int retval = 0; - char *hotkeys; int i; if (silent_mode // No dialogs in silent mode ("ex -s") @@ -3414,7 +3411,7 @@ int do_dialog(int type, const char *title, const char *message, const char *butt // Since we wait for a keypress, don't make the // user press RETURN as well afterwards. no_wait_return++; - hotkeys = msg_show_console_dialog(message, buttons, dfltbutton); + char *hotkeys = msg_show_console_dialog(message, buttons, dfltbutton); while (true) { // Get a typed character directly from the user. diff --git a/src/nvim/move.c b/src/nvim/move.c index 891aa8f5ce..c4f8eca493 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2703,7 +2703,7 @@ void do_check_cursorbind(void) colnr_T col = curwin->w_cursor.col; colnr_T coladd = curwin->w_cursor.coladd; colnr_T curswant = curwin->w_curswant; - int set_curswant = curwin->w_set_curswant; + bool set_curswant = curwin->w_set_curswant; win_T *old_curwin = curwin; buf_T *old_curbuf = curbuf; int old_VIsual_select = VIsual_select; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 8083bb00f5..d9988cb94b 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4721,7 +4721,7 @@ static void nv_vreplace(cmdarg_T *cap) /// Swap case for "~" command, when it does not work like an operator. static void n_swapchar(cmdarg_T *cap) { - int did_change = 0; + bool did_change = false; if (checkclearopq(cap->oap)) { return; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 71c2c7930e..6f5f209a71 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1496,7 +1496,7 @@ int op_delete(oparg_T *oap) // register. For the black hole register '_' don't yank anything. if (oap->regname != '_') { yankreg_T *reg = NULL; - int did_yank = false; + bool did_yank = false; if (oap->regname != 0) { // check for read-only register if (!valid_yank_reg(oap->regname, true)) { @@ -1794,7 +1794,7 @@ static int op_replace(oparg_T *oap, int c) int n; struct block_def bd; char *after_p = NULL; - int had_ctrl_v_cr = false; + bool had_ctrl_v_cr = false; if ((curbuf->b_ml.ml_flags & ML_EMPTY) || oap->empty) { return OK; // nothing to do @@ -2638,7 +2638,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) case kMTCharWise: { colnr_T startcol = 0; colnr_T endcol = MAXCOL; - int is_oneChar = false; + bool is_oneChar = false; colnr_T cs, ce; char *p = ml_get(lnum); bd.startspaces = 0; @@ -3696,7 +3696,7 @@ void adjust_cursor_eol(void) } /// @return true if lines starting with '#' should be left aligned. -int preprocs_left(void) +bool preprocs_left(void) { return ((curbuf->b_p_si && !curbuf->b_p_cin) || (curbuf->b_p_cin && in_cinkeys('#', ' ', true) @@ -3956,7 +3956,7 @@ char *skip_comment(char *line, bool process, bool include_space, bool *is_commen /// to set those marks. /// /// @return FAIL for failure, OK otherwise -int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions, bool setmark) +int do_join(size_t count, bool insert_space, bool save_undo, bool use_formatoptions, bool setmark) { char *curr = NULL; char *curr_start = NULL; @@ -3967,8 +3967,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions int sumsize = 0; // size of the long new line int ret = OK; int *comments = NULL; - int remove_comments = (use_formatoptions == true) - && has_format_option(FO_REMOVE_COMS); + bool remove_comments = use_formatoptions && has_format_option(FO_REMOVE_COMS); bool prev_was_comment = false; assert(count >= 1); diff --git a/src/nvim/option.c b/src/nvim/option.c index ce4ca92ae8..b1bc34744c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4054,7 +4054,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) return FAIL; } } else { // string - int do_endif = false; + bool do_endif = false; // Don't set 'syntax' and 'filetype' again if the value is // already right, avoids reloading the syntax file. @@ -4779,9 +4779,9 @@ static void init_buf_opt_idx(void) /// BCO_NOHELP Don't copy the values to a help buffer. void buf_copy_options(buf_T *buf, int flags) { - int should_copy = true; + bool should_copy = true; char *save_p_isk = NULL; // init for GCC - int did_isk = false; + bool did_isk = false; // Skip this when the option defaults have not been set yet. Happens when // main() allocates the first buffer. @@ -5120,7 +5120,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) char nextchar; uint32_t flags = 0; OptIndex opt_idx = 0; - int is_term_option = false; + bool is_term_option = false; if (*arg == '<') { while (*p != '>') { diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index 5db7a19411..b9657beb7a 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -190,7 +190,7 @@ void free_users(void) /// Done only once and then cached. static void init_users(void) { - static int lazy_init_done = false; + static bool lazy_init_done = false; if (lazy_init_done) { return; diff --git a/src/nvim/path.c b/src/nvim/path.c index 0fc461ae0f..1d34f5400e 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -236,9 +236,9 @@ char *get_past_head(const char *path) return (char *)retval; } -/// Return true if 'c' is a path separator. +/// @return true if 'c' is a path separator. /// Note that for MS-Windows this includes the colon. -int vim_ispathsep(int c) +bool vim_ispathsep(int c) { #ifdef UNIX return c == '/'; // Unix has ':' inside file names @@ -252,7 +252,7 @@ int vim_ispathsep(int c) } // Like vim_ispathsep(c), but exclude the colon for MS-Windows. -int vim_ispathsep_nocolon(int c) +bool vim_ispathsep_nocolon(int c) { return vim_ispathsep(c) #ifdef BACKSLASH_IN_FILENAME @@ -261,8 +261,8 @@ int vim_ispathsep_nocolon(int c) ; } -/// return true if 'c' is a path list separator. -int vim_ispathlistsep(int c) +/// @return true if 'c' is a path list separator. +bool vim_ispathlistsep(int c) { #ifdef UNIX return c == ':'; @@ -970,20 +970,17 @@ static void uniquefy_paths(garray_T *gap, char *pattern) for (int i = 0; i < gap->ga_len && !got_int; i++) { char *path = fnames[i]; - int is_in_curdir; const char *dir_end = gettail_dir(path); - char *pathsep_p; - char *path_cutoff; len = strlen(path); - is_in_curdir = path_fnamencmp(curdir, path, (size_t)(dir_end - path)) == 0 - && curdir[dir_end - path] == NUL; + bool is_in_curdir = path_fnamencmp(curdir, path, (size_t)(dir_end - path)) == 0 + && curdir[dir_end - path] == NUL; if (is_in_curdir) { in_curdir[i] = xstrdup(path); } // Shorten the filename while maintaining its uniqueness - path_cutoff = get_path_cutoff(path, &path_ga); + char *path_cutoff = get_path_cutoff(path, &path_ga); // Don't assume all files can be reached without path when search // pattern starts with **/, so only remove path_cutoff @@ -998,7 +995,7 @@ static void uniquefy_paths(garray_T *gap, char *pattern) } else { // Here all files can be reached without path, so get shortest // unique path. We start at the end of the path. */ - pathsep_p = path + len - 1; + char *pathsep_p = path + len - 1; while (find_previous_pathsep(path, &pathsep_p)) { if (vim_regexec(®match, pathsep_p + 1, 0) && is_unique(pathsep_p + 1, gap, i) @@ -1353,7 +1350,7 @@ void FreeWild(int count, char **files) } /// @return true if we can expand this backtick thing here. -static int vim_backtick(char *p) +static bool vim_backtick(char *p) { return *p == '`' && *(p + 1) != NUL && *(p + strlen(p) - 1) == '`'; } @@ -2237,7 +2234,7 @@ int expand_wildcards(int num_pat, char **pat, int *num_files, char ***files, int } /// @return true if "fname" matches with an entry in 'suffixes'. -int match_suffix(char *fname) +bool match_suffix(char *fname) { #define MAXSUFLEN 30 // maximum length of a file suffix char suf_buf[MAXSUFLEN]; @@ -2392,7 +2389,7 @@ static int path_to_absolute(const char *fname, char *buf, size_t len, int force) /// Check if file `fname` is a full (absolute) path. /// /// @return `true` if "fname" is absolute. -int path_is_absolute(const char *fname) +bool path_is_absolute(const char *fname) { #ifdef MSWIN if (*fname == NUL) { diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index a3e92fb595..c1f13c1115 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -810,7 +810,7 @@ win_T *pum_set_info(int pum_idx, char *info) /// menu must be recomputed. static bool pum_set_selected(int n, int repeat) { - int resized = false; + bool resized = false; int context = pum_height / 2; int prev_selected = pum_selected; diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 976b7e837d..e25f6b9b5e 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5689,7 +5689,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin return NULL; } - int failed = true; + bool failed = true; bufref_T newbufref; set_bufref(&newbufref, newbuf); @@ -7318,7 +7318,7 @@ void free_quickfix(void) } #endif -static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) +static void get_qf_loc_list(bool is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) { if (what_arg->v_type == VAR_UNKNOWN) { tv_list_alloc_ret(rettv, kListLenMayKnow); diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index d0305a1082..7dfbdd888a 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -2757,7 +2757,7 @@ void ex_finish(exarg_T *eap) /// Mark a sourced file as finished. Possibly makes the ":finish" pending. /// Also called for a pending finish at the ":endtry" or after returning from /// an extra do_cmdline(). "reanimate" is used in the latter case. -void do_finish(exarg_T *eap, int reanimate) +void do_finish(exarg_T *eap, bool reanimate) { if (reanimate) { ((struct source_cookie *)getline_cookie(eap->getline, diff --git a/src/nvim/sign.c b/src/nvim/sign.c index f901f371ce..2bf328bf75 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -721,7 +721,7 @@ static int parse_sign_cmd_args(int cmd, char *arg, char **name, int *id, char ** { char *arg1 = arg; char *filename = NULL; - int lnum_arg = false; + bool lnum_arg = false; // first arg could be placed sign id if (ascii_isdigit(*arg)) { diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index f4ffa2a6b8..7fda93834d 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -696,7 +696,7 @@ void draw_tabline(void) win_T *wp; int attr_nosel = HL_ATTR(HLF_TP); int attr_fill = HL_ATTR(HLF_TPF); - int use_sep_chars = (t_colors < 8); + bool use_sep_chars = (t_colors < 8); if (default_grid.chars == NULL) { return; @@ -772,7 +772,7 @@ void draw_tabline(void) grid_line_put_schar(col++, schar_from_ascii(' '), attr); - int modified = false; + bool modified = false; for (wincount = 0; wp != NULL; wp = wp->w_next, wincount++) { if (bufIsChanged(wp->w_buffer)) { @@ -959,8 +959,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // If "fmt" was set insecurely it needs to be evaluated in the sandbox. // "opt_idx" will be kOptInvalid when caller is nvim_eval_statusline(). - const int use_sandbox = (opt_idx != kOptInvalid) ? was_set_insecurely(wp, opt_idx, opt_scope) - : false; + const bool use_sandbox = (opt_idx != kOptInvalid) ? was_set_insecurely(wp, opt_idx, opt_scope) + : false; // When the format starts with "%!" then evaluate it as an expression and // use the result as the actual format string. diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 2a5777a774..9bddc01f02 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -1900,7 +1900,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st case 'G': { // floating point char format[40]; - int remove_trailing_zeroes = false; + bool remove_trailing_zeroes = false; double f = (tvs ? tv_float(tvs, &arg_idx) diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index f6f0fca74a..d5ee93914a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -4811,12 +4811,9 @@ static char *get_syn_pattern(char *arg, synpat_T *ci) static void syn_cmd_sync(exarg_T *eap, int syncing) { char *arg_start = eap->arg; - char *arg_end; char *key = NULL; - char *next_arg; - int illegal = false; - int finished = false; - char *cpo_save; + bool illegal = false; + bool finished = false; if (ends_excmd(*arg_start)) { syn_cmd_list(eap, true); @@ -4824,8 +4821,8 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) } while (!ends_excmd(*arg_start)) { - arg_end = skiptowhite(arg_start); - next_arg = skipwhite(arg_end); + char *arg_end = skiptowhite(arg_start); + char *next_arg = skipwhite(arg_end); xfree(key); key = vim_strnsave_up(arg_start, (size_t)(arg_end - arg_start)); if (strcmp(key, "CCOMMENT") == 0) { @@ -4895,7 +4892,7 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic; // Make 'cpoptions' empty, to avoid the 'l' flag - cpo_save = p_cpo; + char *cpo_save = p_cpo; p_cpo = empty_string_option; curwin->w_s->b_syn_linecont_prog = vim_regcomp(curwin->w_s->b_syn_linecont_pat, RE_MAGIC); diff --git a/src/nvim/tag.c b/src/nvim/tag.c index e67fa337b3..fb798a06fd 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -207,8 +207,8 @@ static char *tagmatchname = NULL; // name of last used tag // normal tagstack. static taggy_T ptag_entry = { NULL, INIT_FMARK, 0, 0, NULL }; -static int tfu_in_use = false; // disallow recursive call of tagfunc -static Callback tfu_cb; // 'tagfunc' callback function +static bool tfu_in_use = false; // disallow recursive call of tagfunc +static Callback tfu_cb; // 'tagfunc' callback function // Used instead of NUL to separate tag fields in the growarrays. #define TAG_SEP 0x02 @@ -287,17 +287,17 @@ void do_tag(char *tag, int type, int count, int forceit, int verbose) int cur_fnum = curbuf->b_fnum; int oldtagstackidx = tagstackidx; int prevtagstackidx = tagstackidx; - int new_tag = false; - int no_regexp = false; + bool new_tag = false; + bool no_regexp = false; int error_cur_match = 0; - int save_pos = false; + bool save_pos = false; fmark_T saved_fmark; int new_num_matches; char **new_matches; - int use_tagstack; - int skip_msg = false; + bool use_tagstack; + bool skip_msg = false; char *buf_ffname = curbuf->b_ffname; // name for priority computation - int use_tfu = 1; + bool use_tfu = true; char *tofree = NULL; // remember the matches for the last used tag @@ -323,7 +323,7 @@ void do_tag(char *tag, int type, int count, int forceit, int verbose) if (type == DT_HELP) { type = DT_TAG; no_regexp = true; - use_tfu = 0; + use_tfu = false; } int prev_num_matches = num_matches; @@ -792,7 +792,7 @@ end_do_tag: } // List all the matching tags. -static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char **matches) +static void print_tag_list(bool new_tag, bool use_tagstack, int num_matches, char **matches) { taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 3484d104fd..1b9732c5b2 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -870,7 +870,7 @@ void op_formatexpr(oparg_T *oap) /// @param c character to be inserted int fex_format(linenr_T lnum, long count, int c) { - int use_sandbox = was_set_insecurely(curwin, kOptFormatexpr, OPT_LOCAL); + bool use_sandbox = was_set_insecurely(curwin, kOptFormatexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Set v:lnum to the first line number and v:count to the number of lines. diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c index 6e61e9be61..3a7cc2a633 100644 --- a/src/nvim/textobject.c +++ b/src/nvim/textobject.c @@ -586,7 +586,7 @@ int current_word(oparg_T *oap, int count, bool include, bool bigword) { pos_T start_pos; bool inclusive = true; - int include_white = false; + bool include_white = false; cls_bigword = bigword; clearpos(&start_pos); @@ -1079,7 +1079,7 @@ int current_tagblock(oparg_T *oap, int count_arg, bool include) bool do_include = include; bool save_p_ws = p_ws; int retval = FAIL; - int is_inclusive = true; + bool is_inclusive = true; p_ws = false; -- cgit From 674a20ac479d25b23b6f9e99e277a57d2a9d67bc Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 19 Dec 2023 21:25:33 +0800 Subject: test: sign on wrapped line with signcolumn=number (#26654) --- src/nvim/drawscreen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 94eeb9bc77..9a5cfc7d07 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -954,7 +954,6 @@ int showmode(void) lines_left = 0; if (do_mode) { - int sub_attr; msg_puts_attr("--", attr); // CTRL-X in Insert mode if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) { @@ -981,7 +980,8 @@ int showmode(void) } if (edit_submode_extra != NULL) { msg_puts_attr(" ", attr); // Add a space in between. - if ((int)edit_submode_highl < HLF_COUNT) { + int sub_attr; + if (edit_submode_highl < HLF_COUNT) { sub_attr = win_hl_attr(curwin, (int)edit_submode_highl); } else { sub_attr = attr; -- cgit From a61d8b615cf99e317fd78a5c9b39aed90908fc51 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 20 Dec 2023 05:27:18 +0800 Subject: vim-patch:9.0.2178: reg_executing() wrong for :normal with range (#26660) Problem: reg_executing() returns wrong result in :normal with range when 'showcmd' is set (after 8.2.4705). Solution: Reset "pending_end_reg_executing" when executing a register. closes: vim/vim#13707 https://github.com/vim/vim/commit/615202bd0ebc1d8e3532f24b9b7232c2fd86b181 --- src/nvim/ops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6f5f209a71..ece7ccc960 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -1160,6 +1160,7 @@ int do_execreg(int regname, int colon, int addcr, int silent) } } reg_executing = regname == 0 ? '"' : regname; // disable the 'q' command + pending_end_reg_executing = false; } return retval; } -- cgit From c95845f3df256c6d0a15e959d2d2133bfe3b2d43 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 20 Dec 2023 05:58:48 +0800 Subject: vim-patch:9.0.2177: Wrong cursor position when dragging out of window (#26661) Problem: Wrong cursor position when dragging out of window. Solution: Don't use ScreenCols[] when mouse is not in current window. closes: vim/vim#13717 https://github.com/vim/vim/commit/ec14924368e23f2430815c009bd554f88de9c57f --- src/nvim/mouse.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 7a7b687385..35db717058 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -1849,13 +1849,13 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) int click_col = mouse_col; // XXX: this doesn't change click_grid if it is 1, even with multigrid - win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col); - // Only use vcols[] after the window was redrawn. Mainly matters - // for tests, a user would not click before redrawing. - if (wp == NULL || wp->w_redr_type != 0) { + if (mouse_find_win(&click_grid, &click_row, &click_col) != curwin + // Only use vcols[] after the window was redrawn. Mainly matters + // for tests, a user would not click before redrawing. + || curwin->w_redr_type != 0) { return; } - ScreenGrid *gp = &wp->w_grid; + ScreenGrid *gp = &curwin->w_grid; int start_row = 0; int start_col = 0; grid_adjust(&gp, &start_row, &start_col); @@ -1891,12 +1891,12 @@ static void mouse_check_grid(colnr_T *vcolp, int *flagsp) if (eol_vcol < 0) { // Empty line or whole line before w_leftcol, // with columns before buffer text - eol_vcol = wp->w_leftcol - 1; + eol_vcol = curwin->w_leftcol - 1; } *vcolp = eol_vcol + (int)(off - off_r); } else { // Empty line or whole line before w_leftcol - *vcolp = click_col - start_col + wp->w_leftcol; + *vcolp = click_col - start_col + curwin->w_leftcol; } } else if (col_from_screen >= 0) { // Use the virtual column from vcols[], it is accurate also after -- cgit From 095bd8d0f8340475319cfa13776d5ec386984859 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 19 Dec 2023 23:39:33 +0100 Subject: fix(buffer): do not filter help buffer Problem: If a help buffer is opened without legacy syntax set (because treesitter is enabled), Vim strips (some) markup. This means the syntax engine fails to parse (some) syntax if treesitter highlighting is disabled again. Solution: Do not strip the help buffer of markup since (legacy or treesitter) highlighting is always enabled in Nvim. Similarly, remove redundant setting of filetype and give the function a more descriptive name. --- src/nvim/buffer.c | 4 ++-- src/nvim/help.c | 41 ++--------------------------------------- 2 files changed, 4 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7660093fc2..c9ae4c3ed3 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -302,9 +302,9 @@ int open_buffer(bool read_stdin, exarg_T *eap, int flags_arg) } #endif - // Help buffer is filtered. + // Help buffer: populate *local-additions* in help.txt if (bt_help(curbuf)) { - fix_help_buffer(); + get_local_additions(); } } else if (read_stdin) { int save_bin = curbuf->b_p_bin; diff --git a/src/nvim/help.c b/src/nvim/help.c index 28b95b2346..b1b53bc0c3 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -642,46 +642,9 @@ void prepare_help_buffer(void) set_buflisted(false); } -/// After reading a help file: May cleanup a help buffer when syntax -/// highlighting is not used. -void fix_help_buffer(void) +/// After reading a help file: if help.txt, populate *local-additions* +void get_local_additions(void) { - // Set filetype to "help". - if (strcmp(curbuf->b_p_ft, "help") != 0) { - curbuf->b_ro_locked++; - set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("help"), OPT_LOCAL); - curbuf->b_ro_locked--; - } - - if (!syntax_present(curwin)) { - bool in_example = false; - for (linenr_T lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) { - char *line = ml_get_buf(curbuf, lnum); - const size_t len = strlen(line); - if (in_example && len > 0 && !ascii_iswhite(line[0])) { - // End of example: non-white or '<' in first column. - if (line[0] == '<') { - // blank-out a '<' in the first column - line = ml_get_buf_mut(curbuf, lnum); - line[0] = ' '; - } - in_example = false; - } - if (!in_example && len > 0) { - if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' ')) { - // blank-out a '>' in the last column (start of example) - line = ml_get_buf_mut(curbuf, lnum); - line[len - 1] = ' '; - in_example = true; - } else if (line[len - 1] == '~') { - // blank-out a '~' at the end of line (header marker) - line = ml_get_buf_mut(curbuf, lnum); - line[len - 1] = ' '; - } - } - } - } - // In the "help.txt" and "help.abx" file, add the locally added help // files. This uses the very first line in the help file. char *const fname = path_tail(curbuf->b_fname); -- cgit From 0c120307ca1ab613e63865c634d7e10ad67fb0ba Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 20 Dec 2023 14:32:22 +0100 Subject: refactor: eliminate cyclic includes --- src/nvim/api/autocmd.c | 1 + src/nvim/api/deprecated.c | 1 + src/nvim/api/options.c | 1 + src/nvim/api/vimscript.c | 1 + src/nvim/api/win_config.c | 1 + src/nvim/autocmd.h | 1 + src/nvim/base64.c | 1 - src/nvim/buffer_defs.h | 31 ++++++++++-------------- src/nvim/change.c | 1 + src/nvim/channel.c | 1 + src/nvim/charset.c | 1 + src/nvim/cursor.c | 1 + src/nvim/debugger.c | 2 ++ src/nvim/decoration.c | 1 + src/nvim/decoration.h | 2 +- src/nvim/eval/userfunc.c | 1 + src/nvim/ex_cmds2.c | 1 + src/nvim/ex_cmds_defs.h | 1 + src/nvim/ex_session.c | 1 + src/nvim/extmark.c | 1 + src/nvim/file_search.c | 1 + src/nvim/help.c | 1 - src/nvim/highlight_group.c | 1 + src/nvim/indent_c.c | 1 + src/nvim/lua/executor.c | 1 + src/nvim/mark.c | 2 ++ src/nvim/mark.h | 1 + src/nvim/memfile.c | 1 + src/nvim/memory.c | 1 + src/nvim/memory.h | 1 + src/nvim/menu.c | 1 + src/nvim/normal.c | 1 + src/nvim/os/env.c | 1 + src/nvim/os/input.c | 1 + src/nvim/os/shell.c | 1 + src/nvim/os/signal.c | 1 + src/nvim/path.c | 1 + src/nvim/plines.c | 1 + src/nvim/plines.h | 2 +- src/nvim/popupmenu.c | 1 + src/nvim/quickfix.c | 1 + src/nvim/quickfix.h | 1 + src/nvim/regexp_defs.h | 60 ++++++++++++++++++++++------------------------ src/nvim/runtime.c | 1 + src/nvim/shada.c | 1 + src/nvim/spellfile.c | 1 + src/nvim/state.c | 1 + src/nvim/statusline.c | 1 + src/nvim/syntax_defs.h | 8 +++---- src/nvim/tag.c | 1 + src/nvim/terminal.c | 1 - src/nvim/terminal.h | 5 ++-- src/nvim/textobject.c | 1 + src/nvim/types_defs.h | 6 +++++ src/nvim/ui_compositor.c | 1 + src/nvim/undo_defs.h | 2 -- src/nvim/usercmd.h | 1 + src/nvim/version.h | 1 + src/nvim/vim_defs.h | 7 +++--- src/nvim/winfloat.c | 1 + 60 files changed, 107 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 2ce08bdf40..88d7d985e8 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -20,6 +20,7 @@ #include "nvim/globals.h" #include "nvim/lua/executor.h" #include "nvim/memory.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 27af581ef4..f7bbd61cd3 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -21,6 +21,7 @@ #include "nvim/memory.h" #include "nvim/option.h" #include "nvim/pos_defs.h" +#include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/deprecated.c.generated.h" diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index ea617dffaf..fb461152b4 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -15,6 +15,7 @@ #include "nvim/macros_defs.h" #include "nvim/memory.h" #include "nvim/option.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 3bca988030..6f3f0127d1 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -11,6 +11,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/vimscript.h" #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 4ffe3478d7..be18dba315 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -23,6 +23,7 @@ #include "nvim/pos_defs.h" #include "nvim/strings.h" #include "nvim/syntax.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/window.h" #include "nvim/winfloat.h" diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index b0a5a13026..4aefe8e71b 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -13,6 +13,7 @@ #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/pos_defs.h" +#include "nvim/types_defs.h" // Set by the apply_autocmds_group function if the given event is equal to // EVENT_FILETYPE. Used by the readfile function in order to determine if diff --git a/src/nvim/base64.c b/src/nvim/base64.c index 7f7d121442..a0ba219fa2 100644 --- a/src/nvim/base64.c +++ b/src/nvim/base64.c @@ -3,7 +3,6 @@ #include #include -#include "auto/config.h" #include "nvim/base64.h" #include "nvim/memory.h" diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index dc93243fad..49d2126801 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -4,16 +4,6 @@ #include #include -typedef struct file_buffer buf_T; - -/// Reference to a buffer that stores the value of buf_free_count. -/// bufref_valid() only needs to check "buf" when the count differs. -typedef struct { - buf_T *br_buf; - int br_fnum; - int br_buf_free_count; -} bufref_T; - #include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/arglist_defs.h" @@ -27,11 +17,24 @@ typedef struct { #include "nvim/mapping_defs.h" #include "nvim/mark_defs.h" #include "nvim/marktree_defs.h" +#include "nvim/memline_defs.h" #include "nvim/option_vars.h" +#include "nvim/os/fs_defs.h" #include "nvim/pos_defs.h" +#include "nvim/regexp_defs.h" +#include "nvim/sign_defs.h" #include "nvim/statusline_defs.h" +#include "nvim/terminal.h" #include "nvim/undo_defs.h" +/// Reference to a buffer that stores the value of buf_free_count. +/// bufref_valid() only needs to check "buf" when the count differs. +typedef struct { + buf_T *br_buf; + int br_fnum; + int br_buf_free_count; +} bufref_T; + #define GETFILE_SUCCESS(x) ((x) <= 0) #define MODIFIABLE(buf) (buf->b_p_ma) @@ -80,18 +83,10 @@ typedef struct { // Mask to check for flags that prevent normal writing #define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR) -typedef struct window_S win_T; typedef struct wininfo_S wininfo_T; typedef struct frame_S frame_T; typedef uint64_t disptick_T; // display tick type -#include "nvim/memline_defs.h" -#include "nvim/os/fs_defs.h" -#include "nvim/regexp_defs.h" -#include "nvim/sign_defs.h" -#include "nvim/syntax_defs.h" -#include "nvim/terminal.h" - // The taggy struct is used to store the information about a :tag command. typedef struct taggy { char *tagname; // tag name diff --git a/src/nvim/change.c b/src/nvim/change.c index 99698f2e5d..0154ead8fb 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -44,6 +44,7 @@ #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/textformat.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 42935933e0..8c4fa8f5ad 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -34,6 +34,7 @@ #include "nvim/os/shell.h" #include "nvim/path.h" #include "nvim/rbuffer.h" +#include "nvim/terminal.h" #include "nvim/types_defs.h" #ifdef MSWIN diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 48a9808b31..60a0c77cfa 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -27,6 +27,7 @@ #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 1110fe1e64..bcb2810095 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -22,6 +22,7 @@ #include "nvim/plines.h" #include "nvim/pos_defs.h" #include "nvim/state.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index 000fe13502..35333e4b12 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -8,6 +8,7 @@ #include #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/debugger.h" @@ -32,6 +33,7 @@ #include "nvim/regexp.h" #include "nvim/runtime.h" #include "nvim/state_defs.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" /// batch mode debugging: don't save and restore typeahead. diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index b3fad78f84..a18f30ed41 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -6,6 +6,7 @@ #include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/buffer_defs.h" #include "nvim/decoration.h" #include "nvim/drawscreen.h" #include "nvim/extmark.h" diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 92e0cbc76b..1c072eab20 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -5,7 +5,7 @@ #include #include "klib/kvec.h" -#include "nvim/buffer_defs.h" +#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/decoration_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" #include "nvim/marktree_defs.h" diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 5e943711d1..d0b3fe7993 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -10,6 +10,7 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/debugger.h" diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 1722b7902b..975335ba20 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -39,6 +39,7 @@ #include "nvim/pos_defs.h" #include "nvim/quickfix.h" #include "nvim/runtime.h" +#include "nvim/types_defs.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index cf6282ad06..4abc286a96 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -6,6 +6,7 @@ #include "nvim/eval/typval_defs.h" #include "nvim/ex_eval_defs.h" #include "nvim/normal_defs.h" +#include "nvim/os/time_defs.h" #include "nvim/pos_defs.h" #include "nvim/regexp_defs.h" diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 6ae401a58c..47f92920eb 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -34,6 +34,7 @@ #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/runtime.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index f305b6d506..69b10dd674 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -39,6 +39,7 @@ #include "nvim/marktree.h" #include "nvim/memline.h" #include "nvim/pos_defs.h" +#include "nvim/types_defs.h" #include "nvim/undo.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index acbcaa16c2..76f7b7e1af 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -51,6 +51,7 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/file_search.h" diff --git a/src/nvim/help.c b/src/nvim/help.c index b1b53bc0c3..92807039b3 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -36,7 +36,6 @@ #include "nvim/pos_defs.h" #include "nvim/runtime.h" #include "nvim/strings.h" -#include "nvim/syntax.h" #include "nvim/tag.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 683ad0c8a3..1364d9373c 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -15,6 +15,7 @@ #include "nvim/api/private/validate.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/cursor_shape.h" diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 6c133c1e99..377bd3bfec 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -23,6 +23,7 @@ #include "nvim/search.h" #include "nvim/state_defs.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" // Find result cache for cpp_baseclass diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 77c3f22da8..43a6a12fda 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -16,6 +16,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/cmdexpand_defs.h" #include "nvim/cursor.h" diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 54b1df99a2..69042a6034 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -16,6 +16,7 @@ #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" #include "nvim/extmark.h" +#include "nvim/extmark_defs.h" #include "nvim/fold.h" #include "nvim/gettext.h" #include "nvim/globals.h" @@ -37,6 +38,7 @@ #include "nvim/quickfix.h" #include "nvim/strings.h" #include "nvim/textobject.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" // This file contains routines to maintain and manipulate marks. diff --git a/src/nvim/mark.h b/src/nvim/mark.h index b1a093bee0..ec6862b38f 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -2,6 +2,7 @@ #include "nvim/ascii_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep +#include "nvim/extmark_defs.h" // IWYU pragma: keep #include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/mark_defs.h" // IWYU pragma: export diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index d989600d45..fc877d08a3 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -60,6 +60,7 @@ #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/pos_defs.h" +#include "nvim/types_defs.h" #include "nvim/vim_defs.h" #define MEMFILE_PAGE_SIZE 4096 /// default page size diff --git a/src/nvim/memory.c b/src/nvim/memory.c index feb13384be..3e43771cdf 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -36,6 +36,7 @@ #include "nvim/sign.h" #include "nvim/state_defs.h" #include "nvim/statusline.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/ui_client.h" #include "nvim/ui_compositor.h" diff --git a/src/nvim/memory.h b/src/nvim/memory.h index ffdc4c7366..d425249ab6 100644 --- a/src/nvim/memory.h +++ b/src/nvim/memory.h @@ -2,6 +2,7 @@ #include #include // IWYU pragma: keep +#include #include // IWYU pragma: keep #include "auto/config.h" diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 68a8c9f873..383c9e7817 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -8,6 +8,7 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/cursor.h" diff --git a/src/nvim/normal.c b/src/nvim/normal.c index d9988cb94b..dbcec0721f 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -70,6 +70,7 @@ #include "nvim/tag.h" #include "nvim/textformat.h" #include "nvim/textobject.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 6c14f3d593..5d3fa9f0e6 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -26,6 +26,7 @@ #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/version.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index ed4267dcbb..8765fdea4f 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -8,6 +8,7 @@ #include "nvim/api/private/defs.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 26e3171c5b..26c202741a 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -8,6 +8,7 @@ #include "auto/config.h" #include "klib/kvec.h" #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 4960fa6a19..0b0e59946c 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -7,6 +7,7 @@ #endif #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/eval.h" #include "nvim/event/defs.h" #include "nvim/event/signal.h" diff --git a/src/nvim/path.c b/src/nvim/path.c index 1d34f5400e..be3a2dacb2 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -8,6 +8,7 @@ #include "auto/config.h" #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" #include "nvim/eval.h" diff --git a/src/nvim/plines.c b/src/nvim/plines.c index cbfaa4ace3..461f69ae6c 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -6,6 +6,7 @@ #include #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/decoration.h" #include "nvim/diff.h" diff --git a/src/nvim/plines.h b/src/nvim/plines.h index 7227db4524..38024e622e 100644 --- a/src/nvim/plines.h +++ b/src/nvim/plines.h @@ -3,9 +3,9 @@ #include #include // IWYU pragma: keep -#include "nvim/buffer_defs.h" #include "nvim/marktree_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" /// Argument for lbr_chartabsize(). typedef struct { diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index c1f13c1115..386c13f630 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -38,6 +38,7 @@ #include "nvim/pos_defs.h" #include "nvim/state_defs.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index e25f6b9b5e..59207dba17 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -14,6 +14,7 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/drawscreen.h" diff --git a/src/nvim/quickfix.h b/src/nvim/quickfix.h index 9c49564d57..941aa2f991 100644 --- a/src/nvim/quickfix.h +++ b/src/nvim/quickfix.h @@ -1,5 +1,6 @@ #pragma once +#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/option_defs.h" // IWYU pragma: keep diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index 31bc0e86e8..91d897ee7b 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -15,6 +15,32 @@ #include "nvim/pos_defs.h" #include "nvim/types_defs.h" +enum { + /// The number of sub-matches is limited to 10. + /// The first one (index 0) is the whole match, referenced with "\0". + /// The second one (index 1) is the first sub-match, referenced with "\1". + /// This goes up to the tenth (index 9), referenced with "\9". + NSUBEXP = 10, +}; + +typedef struct regengine regengine_T; + +/// Structure to be used for multi-line matching. +/// Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col" +/// and ends in line "endpos[no].lnum" just before column "endpos[no].col". +/// The line numbers are relative to the first line, thus startpos[0].lnum is +/// always 0. +/// When there is no match, the line number is -1. +typedef struct { + regprog_T *regprog; + lpos_T startpos[NSUBEXP]; + lpos_T endpos[NSUBEXP]; + + colnr_T rmm_matchcol; ///< match start without "\zs" + int rmm_ic; + colnr_T rmm_maxcol; ///< when not zero: maximum column +} regmmatch_T; + /// Used for "magic_overruled". typedef enum { OPTION_MAGIC_NOT_SET, ///< p_magic not overruled @@ -33,14 +59,6 @@ typedef enum { MAGIC_ALL = 4, ///< "\v" very magic } magic_T; -enum { - /// The number of sub-matches is limited to 10. - /// The first one (index 0) is the whole match, referenced with "\0". - /// The second one (index 1) is the first sub-match, referenced with "\1". - /// This goes up to the tenth (index 9), referenced with "\9". - NSUBEXP = 10, -}; - enum { /// In the NFA engine: how many braces are allowed. /// TODO(RE): Use dynamic memory allocation instead of static, like here @@ -61,28 +79,6 @@ enum { NFA_ENGINE = 2, }; -typedef struct regengine regengine_T; -typedef struct regprog regprog_T; -typedef struct reg_extmatch reg_extmatch_T; - -/// Structure to be used for multi-line matching. -/// Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col" -/// and ends in line "endpos[no].lnum" just before column "endpos[no].col". -/// The line numbers are relative to the first line, thus startpos[0].lnum is -/// always 0. -/// When there is no match, the line number is -1. -typedef struct { - regprog_T *regprog; - lpos_T startpos[NSUBEXP]; - lpos_T endpos[NSUBEXP]; - - colnr_T rmm_matchcol; ///< match start without "\zs" - int rmm_ic; - colnr_T rmm_maxcol; ///< when not zero: maximum column -} regmmatch_T; - -#include "nvim/buffer_defs.h" - /// Structure returned by vim_regcomp() to pass on to vim_regexec(). /// This is the general structure. For the actual matcher, two specific /// structures are used. See code below. @@ -164,10 +160,10 @@ typedef struct { /// Structure used to store external references: "\z\(\)" to "\z\1". /// Use a reference count to avoid the need to copy this around. When it goes /// from 1 to zero the matches need to be freed. -struct reg_extmatch { +typedef struct { int16_t refcnt; uint8_t *matches[NSUBEXP]; -}; +} reg_extmatch_T; struct regengine { /// bt_regcomp or nfa_regcomp diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 7dfbdd888a..29b70e05ca 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -17,6 +17,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" #include "nvim/debugger.h" diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 02e7c3cc68..5c479bb1c6 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -50,6 +50,7 @@ #include "nvim/search.h" #include "nvim/shada.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/version.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 027013c5f0..979495e810 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -264,6 +264,7 @@ #include "nvim/spell_defs.h" #include "nvim/spellfile.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/state.c b/src/nvim/state.c index 199003b61c..518ceb8c88 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -3,6 +3,7 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 7fda93834d..d31b8ef0b1 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -40,6 +40,7 @@ #include "nvim/state_defs.h" #include "nvim/statusline.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/window.h" diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h index ae4997154e..8fd8b0638f 100644 --- a/src/nvim/syntax_defs.h +++ b/src/nvim/syntax_defs.h @@ -1,6 +1,9 @@ #pragma once +#include "nvim/buffer_defs.h" +#include "nvim/garray_defs.h" #include "nvim/highlight_defs.h" +#include "nvim/regexp_defs.h" #define SST_MIN_ENTRIES 150 // minimal size for state stack array #define SST_MAX_ENTRIES 1000 // maximal size for state stack array @@ -8,11 +11,6 @@ #define SST_DIST 16 // normal distance between entries #define SST_INVALID ((synstate_T *)-1) // invalid syn_state pointer -typedef struct syn_state synstate_T; - -#include "nvim/buffer_defs.h" -#include "nvim/regexp_defs.h" - // struct passed to in_id_list() struct sp_syn { int inc_tag; // ":syn include" unique tag diff --git a/src/nvim/tag.c b/src/nvim/tag.c index fb798a06fd..8c7b6171aa 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -54,6 +54,7 @@ #include "nvim/state_defs.h" #include "nvim/strings.h" #include "nvim/tag.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index da6bf134de..1586dd3d8e 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -49,7 +49,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/channel.h" #include "nvim/cursor.h" diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h index dd0ef3f47c..1bbc1abd4a 100644 --- a/src/nvim/terminal.h +++ b/src/nvim/terminal.h @@ -4,13 +4,12 @@ #include #include -typedef struct terminal Terminal; +#include "nvim/api/private/defs.h" // IWYU pragma: keep + typedef void (*terminal_write_cb)(const char *buffer, size_t size, void *data); typedef void (*terminal_resize_cb)(uint16_t width, uint16_t height, void *data); typedef void (*terminal_close_cb)(void *data); -#include "nvim/buffer_defs.h" // IWYU pragma: keep - typedef struct { void *data; // PTY process channel uint16_t width, height; diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c index 3a7cc2a633..9c601769c0 100644 --- a/src/nvim/textobject.c +++ b/src/nvim/textobject.c @@ -6,6 +6,7 @@ #include #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/cursor.h" #include "nvim/drawscreen.h" #include "nvim/edit.h" diff --git a/src/nvim/types_defs.h b/src/nvim/types_defs.h index 27227685fa..cc9deb9630 100644 --- a/src/nvim/types_defs.h +++ b/src/nvim/types_defs.h @@ -55,3 +55,9 @@ typedef struct { int add; // Number of signs added in the invalid range, negative for deleted signs. } SignRange; #define SIGNRANGE_INIT { 0, 0 } + +typedef struct file_buffer buf_T; +typedef struct syn_state synstate_T; +typedef struct terminal Terminal; +typedef struct window_S win_T; +typedef struct regprog regprog_T; diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index baad8f3c29..d8969b0061 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -14,6 +14,7 @@ #include "klib/kvec.h" #include "nvim/api/private/defs.h" #include "nvim/ascii_defs.h" +#include "nvim/buffer_defs.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight.h" diff --git a/src/nvim/undo_defs.h b/src/nvim/undo_defs.h index 09a9689f67..e38b5e88fe 100644 --- a/src/nvim/undo_defs.h +++ b/src/nvim/undo_defs.h @@ -18,8 +18,6 @@ typedef struct { colnr_T vi_curswant; ///< MAXCOL from w_curswant } visualinfo_T; -#include "nvim/buffer_defs.h" - typedef struct u_entry u_entry_T; struct u_entry { u_entry_T *ue_next; ///< pointer to next entry in list diff --git a/src/nvim/usercmd.h b/src/nvim/usercmd.h index bcabf9460b..4d6d154b79 100644 --- a/src/nvim/usercmd.h +++ b/src/nvim/usercmd.h @@ -3,6 +3,7 @@ #include // IWYU pragma: keep #include +#include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/version.h b/src/nvim/version.h index 94219aaddc..cc355f2df5 100644 --- a/src/nvim/version.h +++ b/src/nvim/version.h @@ -1,5 +1,6 @@ #pragma once +#include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" diff --git a/src/nvim/vim_defs.h b/src/nvim/vim_defs.h index b6cf402b02..4cd0097cdf 100644 --- a/src/nvim/vim_defs.h +++ b/src/nvim/vim_defs.h @@ -1,13 +1,14 @@ #pragma once +#include "auto/config.h" +#include "nvim/os/os_defs.h" // IWYU pragma: keep + // Some defines from the old feature.h #define SESSION_FILE "Session.vim" #define MAX_MSG_HIST_LEN 200 #define SYS_OPTWIN_FILE "$VIMRUNTIME/optwin.vim" #define RUNTIME_DIRNAME "runtime" -#include "auto/config.h" - enum { /// length of a buffer to store a number in ASCII (64 bits binary + NUL) NUMBUFLEN = 65, @@ -56,8 +57,6 @@ typedef enum { kCdCauseAuto, ///< On 'autochdir'. } CdCause; -#include "nvim/os/os_defs.h" // IWYU pragma: keep - // return values for functions #if !(defined(OK) && (OK == 1)) // OK already defined to 1 in MacOS X curses, skip this diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 87069d5682..dc29c08c14 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -19,6 +19,7 @@ #include "nvim/optionstr.h" #include "nvim/pos_defs.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" #include "nvim/window.h" -- cgit From 342c7da4bd2c60796d722970f82300b6d5ba0b42 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Dec 2023 10:39:10 +0800 Subject: fix(channel): use os_write() instead of fwrite() for stderr (#26689) This handles EAGAIN. Related #26688 --- src/nvim/channel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 8c4fa8f5ad..e62c240636 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -30,6 +30,7 @@ #include "nvim/message.h" #include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/server.h" +#include "nvim/os/fs.h" #include "nvim/os/os_defs.h" #include "nvim/os/shell.h" #include "nvim/path.h" @@ -574,7 +575,10 @@ size_t channel_send(uint64_t id, char *data, size_t len, bool data_owned, const goto retfree; } // unbuffered write - written = len * fwrite(data, len, 1, stderr); + ptrdiff_t wres = os_write(STDERR_FILENO, data, len, false); + if (wres >= 0) { + written = (size_t)wres; + } goto retfree; } -- cgit From 8c611f53feaeb6110875499cec9097c93b892c8c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Dec 2023 15:32:30 +0800 Subject: fixup: --- src/nvim/os/tty.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c index e683b9383f..57325c312f 100644 --- a/src/nvim/os/tty.c +++ b/src/nvim/os/tty.c @@ -2,7 +2,10 @@ // Terminal/console utils // -#include "nvim/os/os.h" // IWYU pragma: keep (Windows) +#ifdef MSWIN +# include "nvim/memory.h" +# include "nvim/os/os.h" +#endif #include "nvim/os/tty.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit From 8533adb4844b771b84dac2141fa2fa60e0487b47 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Dec 2023 16:50:05 +0800 Subject: refactor(IWYU): move decor provider types to decoration_defs.h (#26692) --- src/clint.py | 1 - src/nvim/api/buffer.c | 1 - src/nvim/api/buffer.h | 3 ++- src/nvim/api/vim.c | 1 - src/nvim/base64.c | 1 + src/nvim/buffer.c | 1 - src/nvim/buffer_defs.h | 2 +- src/nvim/bufwrite.c | 2 -- src/nvim/bufwrite.h | 2 +- src/nvim/change.c | 1 - src/nvim/change.h | 4 +++- src/nvim/channel.h | 1 - src/nvim/cursor.h | 2 +- src/nvim/decoration.c | 1 - src/nvim/decoration.h | 2 +- src/nvim/decoration_defs.h | 18 +++++++++++++++ src/nvim/decoration_provider.c | 8 +++++++ src/nvim/decoration_provider.h | 26 ++------------------- src/nvim/digraph.h | 1 - src/nvim/drawline.c | 1 + src/nvim/drawline.h | 9 ++++---- src/nvim/drawscreen.c | 1 - src/nvim/edit.c | 1 - src/nvim/edit.h | 2 +- src/nvim/eval.c | 1 - src/nvim/eval.h | 3 ++- src/nvim/eval/funcs.c | 1 - src/nvim/eval/funcs.h | 1 - src/nvim/ex_cmds2.h | 2 +- src/nvim/extmark.h | 2 +- src/nvim/fileio.c | 1 - src/nvim/fileio.h | 3 ++- src/nvim/fold.h | 3 ++- src/nvim/highlight.c | 1 + src/nvim/indent.h | 1 - src/nvim/indent_c.h | 2 +- src/nvim/memfile.h | 2 +- src/nvim/memline.c | 1 - src/nvim/memline.h | 2 +- src/nvim/memory.h | 2 +- src/nvim/mouse.c | 1 - src/nvim/mouse.h | 1 - src/nvim/move.h | 1 - src/nvim/normal.c | 1 - src/nvim/normal.h | 4 +++- src/nvim/option.c | 1 + src/nvim/optionstr.h | 2 +- src/nvim/os/os.h | 2 +- src/nvim/os/os_win_console.c | 38 ++++++++++++++++++++++++++++++ src/nvim/os/pty_conpty_win.c | 1 + src/nvim/os/pty_process_win.c | 1 + src/nvim/os/tty.c | 52 ------------------------------------------ src/nvim/os/tty.h | 5 ---- src/nvim/popupmenu.c | 1 - src/nvim/popupmenu.h | 2 +- src/nvim/regexp.h | 2 +- src/nvim/search.c | 1 - src/nvim/search.h | 1 - src/nvim/sign.c | 1 - src/nvim/sign.h | 1 - src/nvim/statusline.c | 1 - src/nvim/statusline.h | 2 +- src/nvim/syntax.c | 1 - src/nvim/syntax.h | 2 +- src/nvim/tag.h | 2 +- src/nvim/terminal.h | 1 + src/nvim/tui/tui.c | 1 - src/nvim/undo.h | 2 +- 68 files changed, 110 insertions(+), 141 deletions(-) delete mode 100644 src/nvim/os/tty.c delete mode 100644 src/nvim/os/tty.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 51155f0038..80ebf565a1 100755 --- a/src/clint.py +++ b/src/clint.py @@ -906,7 +906,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/buffer_defs.h", "src/nvim/channel.h", "src/nvim/charset.h", - "src/nvim/drawline.h", "src/nvim/eval.h", "src/nvim/eval/encode.h", "src/nvim/eval/typval.h", diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 99d261e73d..bbb6b92986 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -18,7 +18,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" #include "nvim/change.h" #include "nvim/cursor.h" diff --git a/src/nvim/api/buffer.h b/src/nvim/api/buffer.h index f3971c1d30..fe2d104058 100644 --- a/src/nvim/api/buffer.h +++ b/src/nvim/api/buffer.h @@ -5,7 +5,8 @@ #include "nvim/api/keysets_defs.h" // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/buffer.h.generated.h" diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index aed286165a..9ae5244fa1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -64,7 +64,6 @@ #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/terminal.h" -#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/base64.c b/src/nvim/base64.c index a0ba219fa2..7f7d121442 100644 --- a/src/nvim/base64.c +++ b/src/nvim/base64.c @@ -3,6 +3,7 @@ #include #include +#include "auto/config.h" #include "nvim/base64.h" #include "nvim/memory.h" diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index c9ae4c3ed3..d62e73a191 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -94,7 +94,6 @@ #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/terminal.h" -#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" #include "nvim/usercmd.h" diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 49d2126801..3a6b5e2c6b 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -24,7 +24,7 @@ #include "nvim/regexp_defs.h" #include "nvim/sign_defs.h" #include "nvim/statusline_defs.h" -#include "nvim/terminal.h" +#include "nvim/types_defs.h" #include "nvim/undo_defs.h" /// Reference to a buffer that stores the value of buf_free_count. diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index 67e5fb3b6f..c506cfdfa3 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -13,12 +13,10 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/bufwrite.h" #include "nvim/change.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_eval.h" diff --git a/src/nvim/bufwrite.h b/src/nvim/bufwrite.h index 9ed6216847..ce9e04d2b1 100644 --- a/src/nvim/bufwrite.h +++ b/src/nvim/bufwrite.h @@ -1,8 +1,8 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "bufwrite.h.generated.h" diff --git a/src/nvim/change.c b/src/nvim/change.c index 0154ead8fb..290f527946 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -9,7 +9,6 @@ #include "nvim/assert_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" #include "nvim/change.h" #include "nvim/charset.h" diff --git a/src/nvim/change.h b/src/nvim/change.h index 06155b6da6..bd1094d57e 100644 --- a/src/nvim/change.h +++ b/src/nvim/change.h @@ -1,7 +1,9 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include // IWYU pragma: keep + #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep /// flags for open_line() enum { diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 2b6356b216..7e3e84d918 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -17,7 +17,6 @@ #include "nvim/map_defs.h" #include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/os/pty_process.h" -#include "nvim/terminal.h" #include "nvim/types_defs.h" static inline bool callback_reader_set(CallbackReader reader) diff --git a/src/nvim/cursor.h b/src/nvim/cursor.h index d50976b598..19107dfec9 100644 --- a/src/nvim/cursor.h +++ b/src/nvim/cursor.h @@ -1,7 +1,7 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "cursor.h.generated.h" diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index a18f30ed41..7b3a32167e 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -20,7 +20,6 @@ #include "nvim/move.h" #include "nvim/option_vars.h" #include "nvim/pos_defs.h" -#include "nvim/sign.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "decoration.c.generated.h" diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 1c072eab20..d8fd432880 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -5,11 +5,11 @@ #include #include "klib/kvec.h" -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/decoration_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" #include "nvim/marktree_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/sign_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // actual Decor* data is in decoration_defs.h diff --git a/src/nvim/decoration_defs.h b/src/nvim/decoration_defs.h index 6e7dc08f80..f272753f46 100644 --- a/src/nvim/decoration_defs.h +++ b/src/nvim/decoration_defs.h @@ -125,3 +125,21 @@ typedef struct { // initializes in a valid state for the DecorHighlightInline branch #define DECOR_INLINE_INIT { .ext = false, .data.hl = DECOR_HIGHLIGHT_INLINE_INIT } + +typedef struct { + NS ns_id; + bool active; + LuaRef redraw_start; + LuaRef redraw_buf; + LuaRef redraw_win; + LuaRef redraw_line; + LuaRef redraw_end; + LuaRef hl_def; + LuaRef spell_nav; + int hl_valid; + bool hl_cached; + + uint8_t error_count; +} DecorProvider; + +typedef kvec_withinit_t(DecorProvider *, 4) DecorProviders; diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c index 172eb569c9..39516ff541 100644 --- a/src/nvim/decoration_provider.c +++ b/src/nvim/decoration_provider.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "klib/kvec.h" @@ -8,6 +9,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/buffer_defs.h" #include "nvim/decoration.h" +#include "nvim/decoration_defs.h" #include "nvim/decoration_provider.h" #include "nvim/globals.h" #include "nvim/highlight.h" @@ -16,6 +18,12 @@ #include "nvim/message.h" #include "nvim/pos_defs.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "decoration_provider.c.generated.h" +#endif + +enum { DP_MAX_ERROR = 3, }; + static kvec_t(DecorProvider) decor_providers = KV_INITIAL_VALUE; #define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \ diff --git a/src/nvim/decoration_provider.h b/src/nvim/decoration_provider.h index e0dd67a6f7..ad6fb7ac19 100644 --- a/src/nvim/decoration_provider.h +++ b/src/nvim/decoration_provider.h @@ -1,32 +1,10 @@ #pragma once #include -#include -#include "klib/kvec.h" -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/decoration_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" -#include "nvim/types_defs.h" - -#define DP_MAX_ERROR 3 - -typedef struct { - NS ns_id; - bool active; - LuaRef redraw_start; - LuaRef redraw_buf; - LuaRef redraw_win; - LuaRef redraw_line; - LuaRef redraw_end; - LuaRef hl_def; - LuaRef spell_nav; - int hl_valid; - bool hl_cached; - - uint8_t error_count; -} DecorProvider; - -typedef kvec_withinit_t(DecorProvider *, 4) DecorProviders; +#include "nvim/types_defs.h" // IWYU pragma: keep EXTERN bool provider_active INIT( = false); diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h index 267004124b..a3782cdd58 100644 --- a/src/nvim/digraph.h +++ b/src/nvim/digraph.h @@ -1,6 +1,5 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/garray_defs.h" // IWYU pragma: keep diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index ee1cd0a3ce..4f62fda2c5 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -15,6 +15,7 @@ #include "nvim/cursor.h" #include "nvim/cursor_shape.h" #include "nvim/decoration.h" +#include "nvim/decoration_defs.h" #include "nvim/decoration_provider.h" #include "nvim/diff.h" #include "nvim/drawline.h" diff --git a/src/nvim/drawline.h b/src/nvim/drawline.h index 5a7f220a13..97a6ca2eee 100644 --- a/src/nvim/drawline.h +++ b/src/nvim/drawline.h @@ -4,14 +4,13 @@ #include #include "klib/kvec.h" -#include "nvim/decoration_provider.h" -#include "nvim/fold_defs.h" +#include "nvim/decoration_defs.h" // IWYU pragma: keep +#include "nvim/fold_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/pos_defs.h" #include "nvim/types_defs.h" -// Maximum columns for terminal highlight attributes -#define TERM_ATTRS_MAX 1024 +enum { TERM_ATTRS_MAX = 1024, }; ///< Maximum columns for terminal highlight attributes typedef struct { NS ns_id; @@ -23,7 +22,7 @@ EXTERN kvec_t(WinExtmark) win_extmark_arr INIT( = KV_INITIAL_VALUE); EXTERN bool conceal_cursor_used INIT( = false); -// Spell checking variables passed from win_update() to win_line(). +/// Spell checking variables passed from win_update() to win_line(). typedef struct { bool spv_has_spell; ///< drawn window has spell checking bool spv_unchanged; ///< not updating for changed text diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 9a5cfc7d07..8a441901d9 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -105,7 +105,6 @@ #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/terminal.h" -#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" #include "nvim/version.h" diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 0fcb665f0f..613aa2a591 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -18,7 +18,6 @@ #include "nvim/drawscreen.h" #include "nvim/edit.h" #include "nvim/eval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/extmark.h" diff --git a/src/nvim/edit.h b/src/nvim/edit.h index 434b653f7b..2f15e737be 100644 --- a/src/nvim/edit.h +++ b/src/nvim/edit.h @@ -1,8 +1,8 @@ #pragma once #include "nvim/autocmd_defs.h" // IWYU pragma: keep -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep /// Values for in_cinkeys() enum { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 21bb325e37..d12a49e7d4 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16,7 +16,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/channel.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 65f7020295..b350b9a8d1 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -4,18 +4,19 @@ #include #include -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/channel.h" #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/event/time.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/grid_defs.h" // IWYU pragma: keep #include "nvim/hashtab_defs.h" #include "nvim/macros_defs.h" #include "nvim/mbyte_defs.h" // IWYU pragma: keep #include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/os/fileio_defs.h" // IWYU pragma: keep #include "nvim/os/stdpaths_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #include "nvim/vim_defs.h" // IWYU pragma: keep #define COPYID_INC 2 diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index f13235c3e9..5b6904269d 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -28,7 +28,6 @@ #include "nvim/assert_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/channel.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" diff --git a/src/nvim/eval/funcs.h b/src/nvim/eval/funcs.h index 0c345dacb4..e3a574b233 100644 --- a/src/nvim/eval/funcs.h +++ b/src/nvim/eval/funcs.h @@ -3,7 +3,6 @@ #include #include -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/pos_defs.h" // IWYU pragma: keep diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h index 4f41f2cc41..a35a27758c 100644 --- a/src/nvim/ex_cmds2.h +++ b/src/nvim/ex_cmds2.h @@ -1,7 +1,7 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep /// flags for check_changed() enum { diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index e83c8d1257..2f2491f8a4 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -4,11 +4,11 @@ #include #include "klib/kvec.h" -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/extmark_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" #include "nvim/marktree_defs.h" #include "nvim/pos_defs.h" +#include "nvim/types_defs.h" // IWYU pragma: keep EXTERN int curbuf_splice_pending INIT( = 0); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 066a150f5a..3e8c4f694c 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -19,7 +19,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" #include "nvim/change.h" #include "nvim/cursor.h" diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h index 32a5ec3002..26161c03ba 100644 --- a/src/nvim/fileio.h +++ b/src/nvim/fileio.h @@ -4,12 +4,13 @@ #include // IWYU pragma: keep #include // IWYU pragma: keep -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/garray_defs.h" // IWYU pragma: keep #include "nvim/os/fs_defs.h" // IWYU pragma: keep +#include "nvim/os/os_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep /// Values for readfile() flags enum { diff --git a/src/nvim/fold.h b/src/nvim/fold.h index efa239daa5..887787578e 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -2,7 +2,8 @@ #include // IWYU pragma: keep -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/decoration_defs.h" // IWYU pragma: keep +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/fold_defs.h" // IWYU pragma: export #include "nvim/garray_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 6684a20607..cffa362d6a 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -11,6 +11,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/api/ui.h" +#include "nvim/decoration_defs.h" #include "nvim/decoration_provider.h" #include "nvim/drawscreen.h" #include "nvim/gettext.h" diff --git a/src/nvim/indent.h b/src/nvim/indent.h index b64015958c..54d27e6243 100644 --- a/src/nvim/indent.h +++ b/src/nvim/indent.h @@ -1,6 +1,5 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep diff --git a/src/nvim/indent_c.h b/src/nvim/indent_c.h index 64ba67a42b..65a402f02c 100644 --- a/src/nvim/indent_c.h +++ b/src/nvim/indent_c.h @@ -1,7 +1,7 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "indent_c.h.generated.h" diff --git a/src/nvim/memfile.h b/src/nvim/memfile.h index 687ac042a4..6e7b575e5b 100644 --- a/src/nvim/memfile.h +++ b/src/nvim/memfile.h @@ -1,7 +1,7 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/memfile_defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep /// flags for mf_sync() enum { diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 25c2de89e0..63f3541b3c 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -48,7 +48,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/cursor.h" #include "nvim/drawscreen.h" diff --git a/src/nvim/memline.h b/src/nvim/memline.h index e70a8e423e..808d97783e 100644 --- a/src/nvim/memline.h +++ b/src/nvim/memline.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/memline_defs.h" // IWYU pragma: export #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep diff --git a/src/nvim/memory.h b/src/nvim/memory.h index d425249ab6..1511876c81 100644 --- a/src/nvim/memory.h +++ b/src/nvim/memory.h @@ -2,7 +2,7 @@ #include #include // IWYU pragma: keep -#include +#include // IWYU pragma: keep #include // IWYU pragma: keep #include "auto/config.h" diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 35db717058..a026859a7e 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -6,7 +6,6 @@ #include "nvim/ascii_defs.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/drawscreen.h" diff --git a/src/nvim/mouse.h b/src/nvim/mouse.h index d787b8ff57..2dcb3469da 100644 --- a/src/nvim/mouse.h +++ b/src/nvim/mouse.h @@ -1,6 +1,5 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/normal_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep diff --git a/src/nvim/move.h b/src/nvim/move.h index f48de6987b..afeaeba235 100644 --- a/src/nvim/move.h +++ b/src/nvim/move.h @@ -1,6 +1,5 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep #include "nvim/vim_defs.h" // IWYU pragma: keep diff --git a/src/nvim/normal.c b/src/nvim/normal.c index dbcec0721f..3937533d36 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -18,7 +18,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cmdhist.h" diff --git a/src/nvim/normal.h b/src/nvim/normal.h index dbe74712fc..93e3e09c2e 100644 --- a/src/nvim/normal.h +++ b/src/nvim/normal.h @@ -1,9 +1,11 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include // IWYU pragma: keep + #include "nvim/macros_defs.h" #include "nvim/normal_defs.h" // IWYU pragma: export #include "nvim/pos_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep /// Values for find_ident_under_cursor() enum { diff --git a/src/nvim/option.c b/src/nvim/option.c index b1bc34744c..49a8c468d6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -38,6 +38,7 @@ #include "nvim/cmdexpand.h" #include "nvim/cmdexpand_defs.h" #include "nvim/cursor_shape.h" +#include "nvim/decoration_defs.h" #include "nvim/decoration_provider.h" #include "nvim/diff.h" #include "nvim/drawscreen.h" diff --git a/src/nvim/optionstr.h b/src/nvim/optionstr.h index b317e55b7e..ae35d706aa 100644 --- a/src/nvim/optionstr.h +++ b/src/nvim/optionstr.h @@ -2,9 +2,9 @@ #include // IWYU pragma: keep -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/option_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "optionstr.h.generated.h" diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 302d84d066..7ba5f05448 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -4,11 +4,11 @@ #include // IWYU pragma: keep #include // IWYU pragma: keep -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/garray_defs.h" // IWYU pragma: keep #include "nvim/os/os_defs.h" // IWYU pragma: export #include "nvim/os/stdpaths_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep #define HAVE_PATHDEF diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 816e81e997..953d291290 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -1,6 +1,7 @@ #include #include "nvim/globals.h" +#include "nvim/memory.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" @@ -105,3 +106,40 @@ void os_title_reset(void) { SetConsoleTitle(origTitle); } + +#if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) +# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif +/// Guesses the terminal-type. Calls SetConsoleMode() and uv_set_vterm_state() +/// if appropriate. +/// +/// @param[in,out] term Name of the guessed terminal, statically-allocated +/// @param out_fd stdout file descriptor +void os_tty_guess_term(const char **term, int out_fd) +{ + bool conemu_ansi = strequal(os_getenv("ConEmuANSI"), "ON"); + bool vtp = false; + + HANDLE handle = (HANDLE)_get_osfhandle(out_fd); + DWORD dwMode; + if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (SetConsoleMode(handle, dwMode)) { + vtp = true; + } + } + + if (*term == NULL) { + if (vtp) { + *term = "vtpcon"; + } else if (conemu_ansi) { + *term = "conemu"; + } else { + *term = "win32con"; + } + } + + if (conemu_ansi) { + uv_tty_set_vterm_state(UV_TTY_SUPPORTED); + } +} diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c index 53169c0ef8..e7697880af 100644 --- a/src/nvim/os/pty_conpty_win.c +++ b/src/nvim/os/pty_conpty_win.c @@ -1,5 +1,6 @@ #include +#include "nvim/log.h" #include "nvim/os/os.h" #include "nvim/os/pty_conpty_win.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index ca2dce36ea..563a79358c 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,6 +4,7 @@ #include "nvim/ascii_defs.h" #include "nvim/eval/typval.h" +#include "nvim/log.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/os/os.h" diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c deleted file mode 100644 index 57325c312f..0000000000 --- a/src/nvim/os/tty.c +++ /dev/null @@ -1,52 +0,0 @@ -// -// Terminal/console utils -// - -#ifdef MSWIN -# include "nvim/memory.h" -# include "nvim/os/os.h" -#endif -#include "nvim/os/tty.h" - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/tty.c.generated.h" // IWYU pragma: export -#endif - -#ifdef MSWIN -# if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) -# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 -# endif -/// Guesses the terminal-type. Calls SetConsoleMode() and uv_set_vterm_state() -/// if appropriate. -/// -/// @param[in,out] term Name of the guessed terminal, statically-allocated -/// @param out_fd stdout file descriptor -void os_tty_guess_term(const char **term, int out_fd) -{ - bool conemu_ansi = strequal(os_getenv("ConEmuANSI"), "ON"); - bool vtp = false; - - HANDLE handle = (HANDLE)_get_osfhandle(out_fd); - DWORD dwMode; - if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { - dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - if (SetConsoleMode(handle, dwMode)) { - vtp = true; - } - } - - if (*term == NULL) { - if (vtp) { - *term = "vtpcon"; - } else if (conemu_ansi) { - *term = "conemu"; - } else { - *term = "win32con"; - } - } - - if (conemu_ansi) { - uv_tty_set_vterm_state(UV_TTY_SUPPORTED); - } -} -#endif diff --git a/src/nvim/os/tty.h b/src/nvim/os/tty.h deleted file mode 100644 index 3a78573189..0000000000 --- a/src/nvim/os/tty.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/tty.h.generated.h" -#endif diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 386c13f630..df82cb259e 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -12,7 +12,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/drawscreen.h" #include "nvim/eval/typval.h" diff --git a/src/nvim/popupmenu.h b/src/nvim/popupmenu.h index 1e4a1584ea..20a342b841 100644 --- a/src/nvim/popupmenu.h +++ b/src/nvim/popupmenu.h @@ -2,11 +2,11 @@ #include -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/grid_defs.h" #include "nvim/macros_defs.h" #include "nvim/menu_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep /// Used for popup menu items. typedef struct { diff --git a/src/nvim/regexp.h b/src/nvim/regexp.h index 447f4860a9..1414749c2f 100644 --- a/src/nvim/regexp.h +++ b/src/nvim/regexp.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/regexp_defs.h" // IWYU pragma: export #include "nvim/types_defs.h" // IWYU pragma: keep diff --git a/src/nvim/search.c b/src/nvim/search.c index a23d27635f..8279b4857c 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -11,7 +11,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cmdhist.h" diff --git a/src/nvim/search.h b/src/nvim/search.h index 12553c8e74..04a06f75a2 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -3,7 +3,6 @@ #include #include -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/normal_defs.h" // IWYU pragma: keep #include "nvim/os/time_defs.h" diff --git a/src/nvim/sign.c b/src/nvim/sign.c index 2bf328bf75..b52142f721 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -13,7 +13,6 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/cursor.h" diff --git a/src/nvim/sign.h b/src/nvim/sign.h index 1c607bc7de..2b6497c255 100644 --- a/src/nvim/sign.h +++ b/src/nvim/sign.h @@ -1,6 +1,5 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/sign_defs.h" // IWYU pragma: export diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index d31b8ef0b1..01729bc4de 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -10,7 +10,6 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/digraph.h" #include "nvim/drawline.h" diff --git a/src/nvim/statusline.h b/src/nvim/statusline.h index e1038ef2ca..36fc5be68e 100644 --- a/src/nvim/statusline.h +++ b/src/nvim/statusline.h @@ -2,10 +2,10 @@ #include -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/statusline_defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep /// Array defining what should be done when tabline is clicked EXTERN StlClickDefinition *tab_page_click_defs INIT( = NULL); diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index d5ee93914a..41c9703f3b 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -10,7 +10,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand_defs.h" #include "nvim/drawscreen.h" diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h index b9065acf7d..f07ad238d3 100644 --- a/src/nvim/syntax.h +++ b/src/nvim/syntax.h @@ -1,10 +1,10 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/syntax_defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep enum { HL_CONTAINED = 0x01, ///< not used on toplevel diff --git a/src/nvim/tag.h b/src/nvim/tag.h index 87e71c8bef..42196b44b7 100644 --- a/src/nvim/tag.h +++ b/src/nvim/tag.h @@ -1,9 +1,9 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/option_defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep enum { LSIZE = 512, }; ///< max. size of a line in the tags file diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h index 1bbc1abd4a..317003c0d2 100644 --- a/src/nvim/terminal.h +++ b/src/nvim/terminal.h @@ -5,6 +5,7 @@ #include #include "nvim/api/private/defs.h" // IWYU pragma: keep +#include "nvim/types_defs.h" // IWYU pragma: keep typedef void (*terminal_write_cb)(const char *buffer, size_t size, void *data); typedef void (*terminal_resize_cb)(uint16_t width, uint16_t height, void *data); diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index ba4069ecf4..6c0b00f010 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -40,7 +40,6 @@ #ifdef MSWIN # include "nvim/os/os_win_console.h" -# include "nvim/os/tty.h" #endif #define OUTBUF_SIZE 0xffff diff --git a/src/nvim/undo.h b/src/nvim/undo.h index f3a8a60d45..a70b1fe486 100644 --- a/src/nvim/undo.h +++ b/src/nvim/undo.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/buffer_defs.h" // IWYU pragma: keep +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep -- cgit From 2ded2e75f4a6d9a575eeb1600e92c6bb333f8060 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 21 Dec 2023 01:23:06 +0100 Subject: fix(column): avoid exceeding configured 'signcolumn' width --- src/nvim/drawscreen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 8a441901d9..3864177802 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1211,7 +1211,7 @@ static bool win_redraw_signcols(win_T *wp) } else if (wp->w_maxscwidth <= 1 && buf->b_signs_with_text >= (size_t)wp->w_maxscwidth) { width = wp->w_maxscwidth; } else { - width = buf_signcols_validate(wp, buf, false); + width = MIN(wp->w_maxscwidth, buf_signcols_validate(wp, buf, false)); } int scwidth = wp->w_scwidth; -- cgit From e8d3c4cccb9d362952a09216a5a114ee6d024c14 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 20 Dec 2023 16:34:17 +0000 Subject: feat: generate types and docs for v variables --- src/nvim/vvars.lua | 869 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 869 insertions(+) create mode 100644 src/nvim/vvars.lua (limited to 'src') diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua new file mode 100644 index 0000000000..d1b5e13401 --- /dev/null +++ b/src/nvim/vvars.lua @@ -0,0 +1,869 @@ +local M = {} + +M.vars = { + argv = { + type = 'string[]', + desc = [=[ + The command line arguments Vim was invoked with. This is a + list of strings. The first item is the Vim command. + See |v:progpath| for the command with full path. + ]=], + }, + char = { + desc = [=[ + Argument for evaluating 'formatexpr' and used for the typed + character when using in an abbreviation |:map-|. + It is also used by the |InsertCharPre| and |InsertEnter| events. + ]=], + }, + charconvert_from = { + type = 'string', + desc = [=[ + The name of the character encoding of a file to be converted. + Only valid while evaluating the 'charconvert' option. + ]=], + }, + charconvert_to = { + type = 'string', + desc = [=[ + The name of the character encoding of a file after conversion. + Only valid while evaluating the 'charconvert' option. + ]=], + }, + cmdarg = { + type = 'string[]', + desc = [=[ + The extra arguments ("++p", "++enc=", "++ff=") given to a file + read/write command. This is set before an autocommand event + for a file read/write command is triggered. There is a + leading space to make it possible to append this variable + directly after the read/write command. Note: "+cmd" isn't + included here, because it will be executed anyway. + ]=], + }, + collate = { + type = 'string', + desc = [=[ + The current locale setting for collation order of the runtime + environment. This allows Vim scripts to be aware of the + current locale encoding. Technical: it's the value of + LC_COLLATE. When not using a locale the value is "C". + This variable can not be set directly, use the |:language| + command. + See |multi-lang|. + ]=], + }, + cmdbang = { + desc = [=[ + Set like v:cmdarg for a file read/write command. When a "!" + was used the value is 1, otherwise it is 0. Note that this + can only be used in autocommands. For user commands || + can be used. + ]=], + }, + completed_item = { + desc = [=[ + Dictionary containing the most recent |complete-items| after + |CompleteDone|. Empty if the completion failed, or after + leaving and re-entering insert mode. + Note: Plugins can modify the value to emulate the builtin + |CompleteDone| event behavior. + ]=], + }, + count = { + type = 'integer', + desc = [=[ + The count given for the last Normal mode command. Can be used + to get the count before a mapping. Read-only. Example: >vim + :map _x :echo "the count is " .. v:count + < + Note: The is required to remove the line range that you + get when typing ':' after a count. + When there are two counts, as in "3d2w", they are multiplied, + just like what happens in the command, "d6w" for the example. + Also used for evaluating the 'formatexpr' option. + ]=], + }, + count1 = { + type = 'integer', + desc = [=[ + Just like "v:count", but defaults to one when no count is + used. + ]=], + }, + ctype = { + desc = [=[ + The current locale setting for characters of the runtime + environment. This allows Vim scripts to be aware of the + current locale encoding. Technical: it's the value of + LC_CTYPE. When not using a locale the value is "C". + This variable can not be set directly, use the |:language| + command. + See |multi-lang|. + ]=], + }, + dying = { + type = 'integer', + desc = [=[ + Normally zero. When a deadly signal is caught it's set to + one. When multiple signals are caught the number increases. + Can be used in an autocommand to check if Vim didn't + terminate normally. + Example: >vim + :au VimLeave * if v:dying | echo "\nAAAAaaaarrrggghhhh!!!\n" | endif + < + Note: if another deadly signal is caught when v:dying is one, + VimLeave autocommands will not be executed. + ]=], + }, + exiting = { + desc = [=[ + Exit code, or |v:null| before invoking the |VimLeavePre| + and |VimLeave| autocmds. See |:q|, |:x| and |:cquit|. + Example: >vim + :au VimLeave * echo "Exit value is " .. v:exiting + < + ]=], + }, + echospace = { + type = 'integer', + desc = [=[ + Number of screen cells that can be used for an `:echo` message + in the last screen line before causing the |hit-enter-prompt|. + Depends on 'showcmd', 'ruler' and 'columns'. You need to + check 'cmdheight' for whether there are full-width lines + available above the last line. + ]=], + }, + errmsg = { + type = 'string', + desc = [=[ + Last given error message. + Modifiable (can be set). + Example: >vim + let v:errmsg = "" + silent! next + if v:errmsg != "" + " ... handle error + < + ]=], + }, + errors = { + tags = { 'assert-return' }, + desc = [=[ + Errors found by assert functions, such as |assert_true()|. + This is a list of strings. + The assert functions append an item when an assert fails. + The return value indicates this: a one is returned if an item + was added to v:errors, otherwise zero is returned. + To remove old results make it empty: >vim + let v:errors = [] + < + If v:errors is set to anything but a list it is made an empty + list by the assert function. + ]=], + }, + event = { + desc = [=[ + Dictionary of event data for the current |autocommand|. Valid + only during the event lifetime; storing or passing v:event is + invalid! Copy it instead: >vim + au TextYankPost * let g:foo = deepcopy(v:event) + < + Keys vary by event; see the documentation for the specific + event, e.g. |DirChanged| or |TextYankPost|. + KEY DESCRIPTION ~ + abort Whether the event triggered during + an aborting condition (e.g. |c_Esc| or + |c_CTRL-C| for |CmdlineLeave|). + chan |channel-id| + cmdlevel Level of cmdline. + cmdtype Type of cmdline, |cmdline-char|. + cwd Current working directory. + inclusive Motion is |inclusive|, else exclusive. + scope Event-specific scope name. + operator Current |operator|. Also set for Ex + commands (unlike |v:operator|). For + example if |TextYankPost| is triggered + by the |:yank| Ex command then + `v:event.operator` is "y". + regcontents Text stored in the register as a + |readfile()|-style list of lines. + regname Requested register (e.g "x" for "xyy) + or the empty string for an unnamed + operation. + regtype Type of register as returned by + |getregtype()|. + visual Selection is visual (as opposed to, + e.g., via motion). + completed_item Current selected complete item on + |CompleteChanged|, Is `{}` when no complete + item selected. + height Height of popup menu on |CompleteChanged| + width Width of popup menu on |CompleteChanged| + row Row count of popup menu on |CompleteChanged|, + relative to screen. + col Col count of popup menu on |CompleteChanged|, + relative to screen. + size Total number of completion items on + |CompleteChanged|. + scrollbar Is |v:true| if popup menu have scrollbar, or + |v:false| if not. + changed_window Is |v:true| if the event fired while + changing window (or tab) on |DirChanged|. + status Job status or exit code, -1 means "unknown". |TermClose| + ]=], + }, + exception = { + desc = [=[ + The value of the exception most recently caught and not + finished. See also |v:throwpoint| and |throw-variables|. + Example: >vim + try + throw "oops" + catch /.*/ + echo "caught " .. v:exception + endtry + < + Output: "caught oops". + ]=], + }, + ['false'] = { + desc = [=[ + Special value used to put "false" in JSON and msgpack. See + |json_encode()|. This value is converted to "v:false" when used + as a String (e.g. in |expr5| with string concatenation + operator) and to zero when used as a Number (e.g. in |expr5| + or |expr7| when used with numeric operators). Read-only. + ]=], + }, + fcs_reason = { + type = 'string', + desc = [=[ + The reason why the |FileChangedShell| event was triggered. + Can be used in an autocommand to decide what to do and/or what + to set v:fcs_choice to. Possible values: + deleted file no longer exists + conflict file contents, mode or timestamp was + changed and buffer is modified + changed file contents has changed + mode mode of file changed + time only file timestamp changed + ]=], + }, + fcs_choice = { + type = 'string', + desc = [=[ + What should happen after a |FileChangedShell| event was + triggered. Can be used in an autocommand to tell Vim what to + do with the affected buffer: + reload Reload the buffer (does not work if + the file was deleted). + edit Reload the buffer and detect the + values for options such as + 'fileformat', 'fileencoding', 'binary' + (does not work if the file was + deleted). + ask Ask the user what to do, as if there + was no autocommand. Except that when + only the timestamp changed nothing + will happen. + Nothing, the autocommand should do + everything that needs to be done. + The default is empty. If another (invalid) value is used then + Vim behaves like it is empty, there is no warning message. + ]=], + }, + fname = { + type = 'string', + desc = [=[ + When evaluating 'includeexpr': the file name that was + detected. Empty otherwise. + ]=], + }, + fname_in = { + type = 'string', + desc = [=[ + The name of the input file. Valid while evaluating: + option used for ~ + 'charconvert' file to be converted + 'diffexpr' original file + 'patchexpr' original file + And set to the swap file name for |SwapExists|. + ]=], + }, + fname_out = { + type = 'string', + desc = [=[ + The name of the output file. Only valid while + evaluating: + option used for ~ + 'charconvert' resulting converted file [1] + 'diffexpr' output of diff + 'patchexpr' resulting patched file + [1] When doing conversion for a write command (e.g., ":w + file") it will be equal to v:fname_in. When doing conversion + for a read command (e.g., ":e file") it will be a temporary + file and different from v:fname_in. + ]=], + }, + fname_new = { + type = 'string', + desc = [=[ + The name of the new version of the file. Only valid while + evaluating 'diffexpr'. + ]=], + }, + fname_diff = { + type = 'string', + desc = [=[ + The name of the diff (patch) file. Only valid while + evaluating 'patchexpr'. + ]=], + }, + folddashes = { + type = 'string', + desc = [=[ + Used for 'foldtext': dashes representing foldlevel of a closed + fold. + Read-only in the |sandbox|. |fold-foldtext| + ]=], + }, + foldlevel = { + type = 'integer', + desc = [=[ + Used for 'foldtext': foldlevel of closed fold. + Read-only in the |sandbox|. |fold-foldtext| + ]=], + }, + foldend = { + type = 'integer', + desc = [=[ + Used for 'foldtext': last line of closed fold. + Read-only in the |sandbox|. |fold-foldtext| + ]=], + }, + foldstart = { + type = 'integer', + desc = [=[ + Used for 'foldtext': first line of closed fold. + Read-only in the |sandbox|. |fold-foldtext| + ]=], + }, + hlsearch = { + type = 'integer', + desc = [=[ + Variable that indicates whether search highlighting is on. + Setting it makes sense only if 'hlsearch' is enabled. Setting + this variable to zero acts like the |:nohlsearch| command, + setting it to one acts like >vim + let &hlsearch = &hlsearch + < + Note that the value is restored when returning from a + function. |function-search-undo|. + ]=], + }, + insertmode = { + type = 'string', + desc = [=[ + Used for the |InsertEnter| and |InsertChange| autocommand + events. Values: + i Insert mode + r Replace mode + v Virtual Replace mode + ]=], + }, + key = { + type = 'string', + desc = [=[ + Key of the current item of a |Dictionary|. Only valid while + evaluating the expression used with |map()| and |filter()|. + Read-only. + ]=], + }, + lang = { + type = 'string', + desc = [=[ + The current locale setting for messages of the runtime + environment. This allows Vim scripts to be aware of the + current language. Technical: it's the value of LC_MESSAGES. + The value is system dependent. + This variable can not be set directly, use the |:language| + command. + It can be different from |v:ctype| when messages are desired + in a different language than what is used for character + encoding. See |multi-lang|. + ]=], + }, + lc_time = { + type = 'string', + desc = [=[ + The current locale setting for time messages of the runtime + environment. This allows Vim scripts to be aware of the + current language. Technical: it's the value of LC_TIME. + This variable can not be set directly, use the |:language| + command. See |multi-lang|. + ]=], + }, + lnum = { + type = 'integer', + desc = [=[ + Line number for the 'foldexpr' |fold-expr|, 'formatexpr', + 'indentexpr' and 'statuscolumn' expressions, tab page number + for 'guitablabel' and 'guitabtooltip'. Only valid while one of + these expressions is being evaluated. Read-only when in the + |sandbox|. + ]=], + }, + lua = { + desc = [=[ + Prefix for calling Lua functions from expressions. + See |v:lua-call| for more information. + ]=], + }, + maxcol = { + type = 'integer', + desc = [=[ + Maximum line length. Depending on where it is used it can be + screen columns, characters or bytes. The value currently is + 2147483647 on all systems. + ]=], + }, + mouse_win = { + type = 'integer', + desc = [=[ + Window number for a mouse click obtained with |getchar()|. + First window has number 1, like with |winnr()|. The value is + zero when there was no mouse button click. + ]=], + }, + mouse_winid = { + type = 'integer', + desc = [=[ + |window-ID| for a mouse click obtained with |getchar()|. + The value is zero when there was no mouse button click. + ]=], + }, + mouse_lnum = { + type = 'integer', + desc = [=[ + Line number for a mouse click obtained with |getchar()|. + This is the text line number, not the screen line number. The + value is zero when there was no mouse button click. + ]=], + }, + mouse_col = { + type = 'integer', + desc = [=[ + Column number for a mouse click obtained with |getchar()|. + This is the screen column number, like with |virtcol()|. The + value is zero when there was no mouse button click. + ]=], + }, + msgpack_types = { + desc = [=[ + Dictionary containing msgpack types used by |msgpackparse()| + and |msgpackdump()|. All types inside dictionary are fixed + (not editable) empty lists. To check whether some list is one + of msgpack types, use |is| operator. + ]=], + }, + null = { + desc = [=[ + Special value used to put "null" in JSON and NIL in msgpack. + See |json_encode()|. This value is converted to "v:null" when + used as a String (e.g. in |expr5| with string concatenation + operator) and to zero when used as a Number (e.g. in |expr5| + or |expr7| when used with numeric operators). Read-only. + In some places `v:null` can be used for a List, Dict, etc. + that is not set. That is slightly different than an empty + List, Dict, etc. + ]=], + }, + numbermax = { + type = 'integer', + desc = 'Maximum value of a number.', + }, + numbermin = { + type = 'integer', + desc = 'Minimum value of a number (negative).', + }, + numbersize = { + type = 'integer', + desc = [=[ + Number of bits in a Number. This is normally 64, but on some + systems it may be 32. + ]=], + }, + oldfiles = { + type = 'string[]', + desc = [=[ + List of file names that is loaded from the |shada| file on + startup. These are the files that Vim remembers marks for. + The length of the List is limited by the ' argument of the + 'shada' option (default is 100). + When the |shada| file is not used the List is empty. + Also see |:oldfiles| and |c_#<|. + The List can be modified, but this has no effect on what is + stored in the |shada| file later. If you use values other + than String this will cause trouble. + ]=], + }, + option_new = { + desc = [=[ + New value of the option. Valid while executing an |OptionSet| + autocommand. + ]=], + }, + option_old = { + desc = [=[ + Old value of the option. Valid while executing an |OptionSet| + autocommand. Depending on the command used for setting and the + kind of option this is either the local old value or the + global old value. + ]=], + }, + option_oldlocal = { + desc = [=[ + Old local value of the option. Valid while executing an + |OptionSet| autocommand. + ]=], + }, + option_oldglobal = { + desc = [=[ + Old global value of the option. Valid while executing an + |OptionSet| autocommand. + ]=], + }, + option_type = { + type = 'string', + desc = [=[ + Scope of the set command. Valid while executing an + |OptionSet| autocommand. Can be either "global" or "local" + ]=], + }, + option_command = { + type = 'string', + desc = [=[ + Command used to set the option. Valid while executing an + |OptionSet| autocommand. + value option was set via ~ + "setlocal" |:setlocal| or `:let l:xxx` + "setglobal" |:setglobal| or `:let g:xxx` + "set" |:set| or |:let| + "modeline" |modeline| + ]=], + }, + operator = { + type = 'string', + desc = [=[ + The last operator given in Normal mode. This is a single + character except for commands starting with or , + in which case it is two characters. Best used alongside + |v:prevcount| and |v:register|. Useful if you want to cancel + Operator-pending mode and then use the operator, e.g.: >vim + :omap O :call MyMotion(v:operator) + < + The value remains set until another operator is entered, thus + don't expect it to be empty. + v:operator is not set for |:delete|, |:yank| or other Ex + commands. + Read-only. + ]=], + }, + prevcount = { + type = 'integer', + desc = [=[ + The count given for the last but one Normal mode command. + This is the v:count value of the previous command. Useful if + you want to cancel Visual or Operator-pending mode and then + use the count, e.g.: >vim + :vmap % :call MyFilter(v:prevcount) + < + Read-only. + ]=], + }, + profiling = { + type = 'integer', + desc = [=[ + Normally zero. Set to one after using ":profile start". + See |profiling|. + ]=], + }, + progname = { + type = 'string', + desc = [=[ + The name by which Nvim was invoked (with path removed). + Read-only. + ]=], + }, + progpath = { + type = 'string', + desc = [=[ + Absolute path to the current running Nvim. + Read-only. + ]=], + }, + register = { + type = 'string', + desc = [=[ + The name of the register in effect for the current normal mode + command (regardless of whether that command actually used a + register). Or for the currently executing normal mode mapping + (use this in custom commands that take a register). + If none is supplied it is the default register '"', unless + 'clipboard' contains "unnamed" or "unnamedplus", then it is + "*" or '+'. + Also see |getreg()| and |setreg()| + ]=], + }, + relnum = { + type = 'integer', + desc = [=[ + Relative line number for the 'statuscolumn' expression. + Read-only. + ]=], + }, + scrollstart = { + desc = [=[ + String describing the script or function that caused the + screen to scroll up. It's only set when it is empty, thus the + first reason is remembered. It is set to "Unknown" for a + typed command. + This can be used to find out why your script causes the + hit-enter prompt. + ]=], + }, + servername = { + type = 'string', + desc = [=[ + Primary listen-address of Nvim, the first item returned by + |serverlist()|. Usually this is the named pipe created by Nvim + at |startup| or given by |--listen| (or the deprecated + |$NVIM_LISTEN_ADDRESS| env var). + + See also |serverstart()| |serverstop()|. + Read-only. + + *$NVIM* + $NVIM is set by |terminal| and |jobstart()|, and is thus + a hint that the current environment is a subprocess of Nvim. + Example: >vim + if $NVIM + echo nvim_get_chan_info(v:parent) + endif + < + + Note the contents of $NVIM may change in the future. + ]=], + }, + searchforward = { + type = 'integer', + desc = [=[ + Search direction: 1 after a forward search, 0 after a + backward search. It is reset to forward when directly setting + the last search pattern, see |quote/|. + Note that the value is restored when returning from a + function. |function-search-undo|. + Read-write. + ]=], + }, + shell_error = { + type = 'string', + desc = [=[ + Result of the last shell command. When non-zero, the last + shell command had an error. When zero, there was no problem. + This only works when the shell returns the error code to Vim. + The value -1 is often used when the command could not be + executed. Read-only. + Example: >vim + !mv foo bar + if v:shell_error + echo 'could not rename "foo" to "bar"!' + endif + < + ]=], + }, + statusmsg = { + type = 'string', + desc = [=[ + Last given status message. + Modifiable (can be set). + ]=], + }, + stderr = { + type = 'string', + desc = [=[ + |channel-id| corresponding to stderr. The value is always 2; + use this variable to make your code more descriptive. + Unlike stdin and stdout (see |stdioopen()|), stderr is always + open for writing. Example: >vim + :call chansend(v:stderr, "error: toaster empty\n") + < + ]=], + }, + swapname = { + type = 'string', + desc = [=[ + Name of the swapfile found. + Only valid during |SwapExists| event. + Read-only. + ]=], + }, + swapchoice = { + type = 'string', + desc = [=[ + |SwapExists| autocommands can set this to the selected choice + for handling an existing swapfile: + 'o' Open read-only + 'e' Edit anyway + 'r' Recover + 'd' Delete swapfile + 'q' Quit + 'a' Abort + The value should be a single-character string. An empty value + results in the user being asked, as would happen when there is + no SwapExists autocommand. The default is empty. + ]=], + }, + swapcommand = { + type = 'string', + desc = [=[ + Normal mode command to be executed after a file has been + opened. Can be used for a |SwapExists| autocommand to have + another Vim open the file and jump to the right place. For + example, when jumping to a tag the value is ":tag tagname\r". + For ":edit +cmd file" the value is ":cmd\r". + ]=], + }, + t_blob = { + type = 'integer', + tags = { 'v:t_TYPE' }, + desc = 'Value of |Blob| type. Read-only. See: |type()|', + }, + t_bool = { + type = 'integer', + desc = 'Value of |Boolean| type. Read-only. See: |type()|', + }, + t_dict = { + type = 'integer', + desc = 'Value of |Dictionary| type. Read-only. See: |type()|', + }, + t_float = { + type = 'integer', + desc = 'Value of |Float| type. Read-only. See: |type()|', + }, + t_func = { + type = 'integer', + desc = 'Value of |Funcref| type. Read-only. See: |type()|', + }, + t_list = { + type = 'integer', + desc = 'Value of |List| type. Read-only. See: |type()|', + }, + t_number = { + type = 'integer', + desc = 'Value of |Number| type. Read-only. See: |type()|', + }, + t_string = { + type = 'integer', + desc = 'Value of |String| type. Read-only. See: |type()|', + }, + termresponse = { + desc = [=[ + The value of the most recent OSC or DCS escape sequence + received by Nvim from the terminal. This can be read in a + |TermResponse| event handler after querying the terminal using + another escape sequence. + ]=], + }, + testing = { + desc = [=[ + Must be set before using `test_garbagecollect_now()`. + ]=], + }, + this_session = { + desc = [=[ + Full filename of the last loaded or saved session file. + Empty when no session file has been saved. See |:mksession|. + Modifiable (can be set). + ]=], + }, + throwpoint = { + desc = [=[ + The point where the exception most recently caught and not + finished was thrown. Not set when commands are typed. See + also |v:exception| and |throw-variables|. + Example: >vim + try + throw "oops" + catch /.*/ + echo "Exception from" v:throwpoint + endtry + < + Output: "Exception from test.vim, line 2" + ]=], + }, + ['true'] = { + desc = [=[ + Special value used to put "true" in JSON and msgpack. See + |json_encode()|. This value is converted to "v:true" when used + as a String (e.g. in |expr5| with string concatenation + operator) and to one when used as a Number (e.g. in |expr5| or + |expr7| when used with numeric operators). Read-only. + ]=], + }, + val = { + desc = [=[ + Value of the current item of a |List| or |Dictionary|. Only + valid while evaluating the expression used with |map()| and + |filter()|. Read-only. + ]=], + }, + version = { + type = 'integer', + desc = [=[ + Vim version number: major version times 100 plus minor + version. Vim 5.0 is 500, Vim 5.1 is 501. + Read-only. + Use |has()| to check the Nvim (not Vim) version: >vim + :if has("nvim-0.2.1") + < + ]=], + }, + virtnum = { + type = 'integer', + desc = [=[ + Virtual line number for the 'statuscolumn' expression. + Negative when drawing the status column for virtual lines, zero + when drawing an actual buffer line, and positive when drawing + the wrapped part of a buffer line. + Read-only. + ]=], + }, + vim_did_enter = { + type = 'integer', + desc = [=[ + 0 during startup, 1 just before |VimEnter|. + Read-only. + ]=], + }, + warningmsg = { + type = 'string', + desc = [=[ + Last given warning message. + Modifiable (can be set). + ]=], + }, + windowid = { + type = 'integer', + desc = [=[ + Application-specific window "handle" which may be set by any + attached UI. Defaults to zero. + Note: For Nvim |windows| use |winnr()| or |win_getid()|, see + |window-ID|. + ]=], + }, +} + +return M -- cgit From ade42d531bcc9ca61facfb0524128a8a9f9b2444 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 21 Dec 2023 14:49:46 +0000 Subject: fix(build): teach cmake about vvars --- src/nvim/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index a21a87ad5e..e03a53669b 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -923,6 +923,8 @@ set(GEN_EVAL_FILES ${NVIM_RUNTIME_DIR}/doc/builtin.txt ${NVIM_RUNTIME_DIR}/lua/vim/_meta/options.lua ${NVIM_RUNTIME_DIR}/doc/options.txt + ${NVIM_RUNTIME_DIR}/lua/vim/_meta/vvars.lua + ${NVIM_RUNTIME_DIR}/doc/vvars.txt ) add_custom_command( @@ -933,6 +935,7 @@ add_custom_command( ${PROJECT_SOURCE_DIR}/scripts/gen_eval_files.lua ${PROJECT_SOURCE_DIR}/src/nvim/eval.lua ${PROJECT_SOURCE_DIR}/src/nvim/options.lua + ${PROJECT_SOURCE_DIR}/src/nvim/vvars.lua ${NVIM_RUNTIME_DIR}/doc/api.mpack WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) -- cgit From af93a74a0f4afa9a3a4f55ffdf28141eaf776d22 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 18 Dec 2023 10:55:23 +0100 Subject: refactor: run IWYU on entire repo Reference: https://github.com/neovim/neovim/issues/6371. --- src/clint.py | 4 +-- src/nvim/api/private/converter.h | 2 +- src/nvim/api/private/dispatch.h | 2 +- src/nvim/api/private/helpers.h | 2 +- src/nvim/api/private/validate.h | 2 +- src/nvim/api/ui.c | 3 ++- src/nvim/api/vim.c | 1 + src/nvim/ascii_defs.h | 50 ++++++++++++++++--------------------- src/nvim/autocmd.c | 3 ++- src/nvim/autocmd_defs.h | 1 - src/nvim/base64.c | 2 +- src/nvim/buffer.c | 3 --- src/nvim/buffer.h | 5 +--- src/nvim/buffer_updates.c | 1 - src/nvim/bufwrite.c | 1 + src/nvim/channel.c | 2 +- src/nvim/channel.h | 6 +---- src/nvim/charset.c | 2 +- src/nvim/charset.h | 7 ++---- src/nvim/cmdexpand.c | 3 +-- src/nvim/cursor.c | 1 - src/nvim/decoration.c | 1 - src/nvim/decoration_provider.c | 1 - src/nvim/drawscreen.c | 1 + src/nvim/edit.c | 3 ++- src/nvim/eval.c | 4 +-- src/nvim/eval.h | 3 ++- src/nvim/eval/encode.h | 4 +-- src/nvim/eval/funcs.c | 3 --- src/nvim/eval/typval.c | 3 +-- src/nvim/eval/typval.h | 3 +-- src/nvim/eval/userfunc.h | 2 +- src/nvim/eval/vars.c | 2 +- src/nvim/event/defs.h | 54 ---------------------------------------- src/nvim/event/libuv_process.c | 2 +- src/nvim/event/libuv_process.h | 2 +- src/nvim/event/loop.c | 2 +- src/nvim/event/loop.h | 9 +++---- src/nvim/event/multiqueue.h | 47 +++++++++++++++++++++++++++++++++- src/nvim/event/process.h | 9 ++----- src/nvim/event/rstream.c | 5 ++-- src/nvim/event/rstream.h | 8 ++---- src/nvim/event/signal.c | 2 ++ src/nvim/event/signal.h | 7 ++---- src/nvim/event/socket.c | 2 ++ src/nvim/event/socket.h | 9 ++----- src/nvim/event/stream.c | 1 + src/nvim/event/stream.h | 10 ++------ src/nvim/event/time.c | 1 + src/nvim/event/time.h | 8 ++---- src/nvim/event/wstream.c | 2 +- src/nvim/event/wstream.h | 10 ++------ src/nvim/ex_docmd.c | 5 ++-- src/nvim/ex_getln.c | 1 - src/nvim/ex_session.c | 1 + src/nvim/fold.c | 1 - src/nvim/garray.h | 1 - src/nvim/getchar.c | 3 +-- src/nvim/grid.h | 3 +-- src/nvim/highlight.h | 2 +- src/nvim/input.c | 1 - src/nvim/keycodes.c | 2 +- src/nvim/keycodes.h | 3 +-- src/nvim/log.h | 33 +++++++++++++++++++++++- src/nvim/log_defs.h | 36 --------------------------- src/nvim/lua/executor.c | 4 +-- src/nvim/lua/executor.h | 11 +++----- src/nvim/lua/stdlib.c | 3 +-- src/nvim/lua/xdiff.c | 1 - src/nvim/macros_defs.h | 39 ----------------------------- src/nvim/main.c | 1 - src/nvim/main.h | 1 + src/nvim/map_glyph_cache.c | 1 - src/nvim/mapping.h | 27 +++++++++++++++++--- src/nvim/mark.h | 46 ++++++++++++++++++++++++++++++---- src/nvim/mark_defs.h | 35 -------------------------- src/nvim/marktree.c | 2 +- src/nvim/mbyte.c | 2 +- src/nvim/mbyte.h | 31 +++++++++++++++++++---- src/nvim/memline.c | 1 - src/nvim/memline.h | 4 +++ src/nvim/message.c | 4 +-- src/nvim/msgpack_rpc/channel.c | 1 + src/nvim/msgpack_rpc/helpers.h | 5 +--- src/nvim/msgpack_rpc/server.c | 1 - src/nvim/msgpack_rpc/unpacker.h | 5 +--- src/nvim/ops.c | 2 +- src/nvim/option.h | 3 +++ src/nvim/os/input.c | 1 - src/nvim/os/input.h | 2 +- src/nvim/os/pty_process_unix.c | 1 - src/nvim/os/pty_process_unix.h | 2 +- src/nvim/os/pty_process_win.c | 1 + src/nvim/os/shell.c | 1 - src/nvim/os/signal.c | 1 - src/nvim/os/time.c | 3 ++- src/nvim/popupmenu.c | 1 - src/nvim/regexp.c | 6 ++--- src/nvim/shada.c | 1 - src/nvim/sign.c | 1 - src/nvim/spell_defs.h | 12 --------- src/nvim/spellfile.c | 2 +- src/nvim/state.c | 2 +- src/nvim/statusline.c | 17 ++++++------- src/nvim/terminal.c | 3 +-- src/nvim/textformat.c | 1 - src/nvim/textobject.c | 1 - src/nvim/tui/input.c | 3 +-- src/nvim/tui/input.h | 1 - src/nvim/tui/tui.c | 1 - src/nvim/types_defs.h | 3 ++- src/nvim/ui.h | 2 +- src/nvim/ui_client.c | 2 +- src/nvim/ui_compositor.c | 2 +- src/nvim/undo.c | 2 +- src/nvim/usercmd.c | 1 - src/nvim/usercmd.h | 2 +- src/nvim/version.c | 1 - src/nvim/viml/parser/parser.h | 1 - src/nvim/window.c | 1 - 120 files changed, 308 insertions(+), 418 deletions(-) delete mode 100644 src/nvim/log_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 80ebf565a1..303c3df25d 100755 --- a/src/clint.py +++ b/src/clint.py @@ -897,8 +897,6 @@ def CheckIncludes(filename, lines, error): }): return - # These should be synced with the ignored headers in the `iwyu` target in - # the Makefile. check_includes_ignore = [ "src/nvim/api/private/validate.h", "src/nvim/assert_defs.h", @@ -913,6 +911,7 @@ def CheckIncludes(filename, lines, error): "src/nvim/eval/userfunc.h", "src/nvim/event/libuv_process.h", "src/nvim/event/loop.h", + "src/nvim/event/multiqueue.h", "src/nvim/event/process.h", "src/nvim/event/rstream.h", "src/nvim/event/signal.h", @@ -928,6 +927,7 @@ def CheckIncludes(filename, lines, error): "src/nvim/keycodes.h", "src/nvim/lua/executor.h", "src/nvim/main.h", + "src/nvim/mark.h", "src/nvim/msgpack_rpc/channel_defs.h", "src/nvim/msgpack_rpc/helpers.h", "src/nvim/msgpack_rpc/unpacker.h", diff --git a/src/nvim/api/private/converter.h b/src/nvim/api/private/converter.h index fc82abf332..a5acc56c7c 100644 --- a/src/nvim/api/private/converter.h +++ b/src/nvim/api/private/converter.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/api/private/defs.h" // IWYU pragma: keep +#include "nvim/api/private/defs.h" // IWYU pragma: export #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index b627db6b00..d322c1ceca 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -3,7 +3,7 @@ #include #include -#include "nvim/api/private/defs.h" +#include "nvim/api/private/defs.h" // IWYU pragma: export #include "nvim/memory_defs.h" #include "nvim/types_defs.h" diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 701ce91257..1ee66f906b 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -4,7 +4,7 @@ #include #include "klib/kvec.h" -#include "nvim/api/private/defs.h" +#include "nvim/api/private/defs.h" // IWYU pragma: export #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/ex_eval_defs.h" diff --git a/src/nvim/api/private/validate.h b/src/nvim/api/private/validate.h index d1c977cd6e..692ea46176 100644 --- a/src/nvim/api/private/validate.h +++ b/src/nvim/api/private/validate.h @@ -3,7 +3,7 @@ #include #include -#include "nvim/api/private/defs.h" +#include "nvim/api/private/defs.h" // IWYU pragma: export #include "nvim/api/private/helpers.h" #include "nvim/assert_defs.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 678d23fbeb..82d42d652d 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -15,7 +15,8 @@ #include "nvim/autocmd.h" #include "nvim/channel.h" #include "nvim/eval.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/wstream.h" #include "nvim/globals.h" #include "nvim/grid.h" diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9ae5244fa1..aed286165a 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -64,6 +64,7 @@ #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/terminal.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" #include "nvim/window.h" diff --git a/src/nvim/ascii_defs.h b/src/nvim/ascii_defs.h index 3de04cd9fa..4215157654 100644 --- a/src/nvim/ascii_defs.h +++ b/src/nvim/ascii_defs.h @@ -86,35 +86,6 @@ static inline bool ascii_iswhite(int c) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_iswhite_or_nul(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_isdigit(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_isxdigit(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_isident(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_isbdigit(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_isodigit(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - -static inline bool ascii_isspace(int c) - REAL_FATTR_CONST - REAL_FATTR_ALWAYS_INLINE; - /// Checks if `c` is a space or tab character. /// /// @see {ascii_isdigit} @@ -123,6 +94,9 @@ static inline bool ascii_iswhite(int c) return c == ' ' || c == '\t'; } +static inline bool ascii_iswhite_or_nul(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Checks if `c` is a space or tab character or NUL. /// /// @see {ascii_isdigit} @@ -131,6 +105,9 @@ static inline bool ascii_iswhite_or_nul(int c) return ascii_iswhite(c) || c == NUL; } +static inline bool ascii_isdigit(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Check whether character is a decimal digit. /// /// Library isdigit() function is officially locale-dependent and, for @@ -145,6 +122,9 @@ static inline bool ascii_isdigit(int c) return c >= '0' && c <= '9'; } +static inline bool ascii_isxdigit(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Checks if `c` is a hexadecimal digit, that is, one of 0-9, a-f, A-F. /// /// @see {ascii_isdigit} @@ -155,6 +135,9 @@ static inline bool ascii_isxdigit(int c) || (c >= 'A' && c <= 'F'); } +static inline bool ascii_isident(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Checks if `c` is an “identifier” character /// /// That is, whether it is alphanumeric character or underscore. @@ -163,6 +146,9 @@ static inline bool ascii_isident(int c) return ASCII_ISALNUM(c) || c == '_'; } +static inline bool ascii_isbdigit(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Checks if `c` is a binary digit, that is, 0-1. /// /// @see {ascii_isdigit} @@ -171,6 +157,9 @@ static inline bool ascii_isbdigit(int c) return (c == '0' || c == '1'); } +static inline bool ascii_isodigit(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Checks if `c` is an octal digit, that is, 0-7. /// /// @see {ascii_isdigit} @@ -179,6 +168,9 @@ static inline bool ascii_isodigit(int c) return (c >= '0' && c <= '7'); } +static inline bool ascii_isspace(int c) + REAL_FATTR_CONST + REAL_FATTR_ALWAYS_INLINE; /// Checks if `c` is a white-space character, that is, /// one of \f, \n, \r, \t, \v. /// diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 9605e3b4db..a7fe6667e8 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -19,7 +19,8 @@ #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/fileio.h" diff --git a/src/nvim/autocmd_defs.h b/src/nvim/autocmd_defs.h index 4639ec2731..ec81c2f1ed 100644 --- a/src/nvim/autocmd_defs.h +++ b/src/nvim/autocmd_defs.h @@ -12,7 +12,6 @@ #include "nvim/regexp_defs.h" #include "nvim/types_defs.h" -// event_T definition #ifdef INCLUDE_GENERATED_DECLARATIONS # include "auevents_enum.generated.h" #endif diff --git a/src/nvim/base64.c b/src/nvim/base64.c index 7f7d121442..d461b7e3ff 100644 --- a/src/nvim/base64.c +++ b/src/nvim/base64.c @@ -3,7 +3,7 @@ #include #include -#include "auto/config.h" +#include "auto/config.h" // IWYU pragma: keep #include "nvim/base64.h" #include "nvim/memory.h" diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index d62e73a191..24eab644a1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -43,11 +43,9 @@ #include "nvim/digraph.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/eval/vars.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" -#include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" @@ -69,7 +67,6 @@ #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memfile_defs.h" -#include "nvim/memline_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/move.h" diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h index 36e70d1927..af30870776 100644 --- a/src/nvim/buffer.h +++ b/src/nvim/buffer.h @@ -6,13 +6,10 @@ #include "nvim/buffer_defs.h" // IWYU pragma: export #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" -#include "nvim/ex_cmds_defs.h" #include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/memline.h" -#include "nvim/memline_defs.h" -#include "nvim/pos_defs.h" +#include "nvim/types_defs.h" /// Values for buflist_getfile() enum getf_values { diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index a91a890d0e..7985d6931f 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -5,7 +5,6 @@ #include "klib/kvec.h" #include "nvim/api/buffer.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/assert_defs.h" #include "nvim/buffer.h" diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index c506cfdfa3..7f44cdfb2c 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -17,6 +17,7 @@ #include "nvim/change.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_eval.h" diff --git a/src/nvim/channel.c b/src/nvim/channel.c index e62c240636..d2b064ef3c 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -7,7 +7,6 @@ #include "klib/kvec.h" #include "nvim/api/private/converter.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" @@ -15,6 +14,7 @@ #include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/eval/typval.h" +#include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" #include "nvim/event/socket.h" diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 7e3e84d918..e77f17d3e0 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -7,13 +7,9 @@ #include "nvim/channel_defs.h" // IWYU pragma: export #include "nvim/eval/typval_defs.h" #include "nvim/event/libuv_process.h" -#include "nvim/event/multiqueue.h" #include "nvim/event/process.h" -#include "nvim/event/socket.h" -#include "nvim/event/stream.h" -#include "nvim/garray_defs.h" +#include "nvim/func_attr.h" #include "nvim/macros_defs.h" -#include "nvim/main.h" #include "nvim/map_defs.h" #include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/os/pty_process.h" diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 60a0c77cfa..fc900fd3a7 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "auto/config.h" #include "klib/kvec.h" diff --git a/src/nvim/charset.h b/src/nvim/charset.h index cfab0f8517..62a38660a8 100644 --- a/src/nvim/charset.h +++ b/src/nvim/charset.h @@ -3,12 +3,9 @@ #include #include -#include "nvim/buffer_defs.h" -#include "nvim/eval/typval_defs.h" -#include "nvim/option_defs.h" +#include "nvim/func_attr.h" #include "nvim/option_vars.h" -#include "nvim/pos_defs.h" -#include "nvim/strings.h" +#include "nvim/strings.h" // IWYU pragma: keep /// Return the folded-case equivalent of the given character /// diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 31b385c466..3198156409 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -6,9 +6,8 @@ #include #include #include -#include +#include -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/arglist.h" #include "nvim/ascii_defs.h" diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index bcb2810095..d25566213c 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -11,7 +11,6 @@ #include "nvim/drawscreen.h" #include "nvim/fold.h" #include "nvim/globals.h" -#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 7b3a32167e..ad2482c2e4 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -4,7 +4,6 @@ #include #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/buffer_defs.h" #include "nvim/decoration.h" diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c index 39516ff541..e160a563f3 100644 --- a/src/nvim/decoration_provider.c +++ b/src/nvim/decoration_provider.c @@ -5,7 +5,6 @@ #include "klib/kvec.h" #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/buffer_defs.h" #include "nvim/decoration.h" diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 3864177802..a6e483ab54 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -105,6 +105,7 @@ #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/terminal.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" #include "nvim/version.h" diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 613aa2a591..8984a959d3 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" @@ -18,6 +18,7 @@ #include "nvim/drawscreen.h" #include "nvim/edit.h" #include "nvim/eval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/extmark.h" diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d12a49e7d4..68347fd582 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7,11 +7,10 @@ #include #include #include -#include +#include #include "auto/config.h" #include "nvim/api/private/converter.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" @@ -29,6 +28,7 @@ #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" +#include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/process.h" #include "nvim/event/time.h" diff --git a/src/nvim/eval.h b/src/nvim/eval.h index b350b9a8d1..9ee5d99806 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -4,7 +4,7 @@ #include #include -#include "nvim/channel.h" +#include "nvim/channel_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/event/time.h" @@ -13,6 +13,7 @@ #include "nvim/hashtab_defs.h" #include "nvim/macros_defs.h" #include "nvim/mbyte_defs.h" // IWYU pragma: keep +#include "nvim/msgpack_rpc/channel_defs.h" // IWYU pragma: keep #include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/os/fileio_defs.h" // IWYU pragma: keep #include "nvim/os/stdpaths_defs.h" // IWYU pragma: keep diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h index 11a0ce3932..fe1b951e3c 100644 --- a/src/nvim/eval/encode.h +++ b/src/nvim/eval/encode.h @@ -1,12 +1,10 @@ #pragma once -#include #include -#include #include #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" +#include "nvim/func_attr.h" #include "nvim/garray_defs.h" /// Convert Vimscript value to msgpack string diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 5b6904269d..30a86b1917 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -14,13 +14,11 @@ #include #include #include -#include #include #include #include "auto/config.h" #include "nvim/api/private/converter.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" @@ -47,7 +45,6 @@ #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/eval/window.h" -#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/process.h" diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 069cdced34..42b105b2a2 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "nvim/ascii_defs.h" #include "nvim/assert_defs.h" @@ -19,7 +19,6 @@ #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/garray.h" -#include "nvim/garray_defs.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/hashtab.h" diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index efa6017f4b..0013c8ffe5 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -8,12 +8,11 @@ #include "nvim/eval/typval_defs.h" // IWYU pragma: export #include "nvim/func_attr.h" -#include "nvim/garray_defs.h" #include "nvim/gettext.h" #include "nvim/hashtab.h" #include "nvim/lib/queue.h" #include "nvim/macros_defs.h" -#include "nvim/mbyte_defs.h" +#include "nvim/mbyte_defs.h" // IWYU pragma: keep #include "nvim/message.h" #include "nvim/types_defs.h" diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 8050caab2b..65a96a13c5 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -4,7 +4,7 @@ #include #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep -#include "nvim/eval.h" +#include "nvim/eval.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/hashtab_defs.h" // IWYU pragma: keep diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index de2fddb083..8ed76341b0 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index ffea388b9b..e19ad4c970 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -20,52 +20,6 @@ typedef struct { typedef struct multiqueue MultiQueue; typedef void (*PutCallback)(MultiQueue *multiq, void *data); -#define multiqueue_put(q, h, ...) \ - do { \ - multiqueue_put_event(q, event_create(h, __VA_ARGS__)); \ - } while (0) - -#define CREATE_EVENT(multiqueue, handler, ...) \ - do { \ - if (multiqueue) { \ - multiqueue_put((multiqueue), (handler), __VA_ARGS__); \ - } else { \ - void *argv[] = { __VA_ARGS__ }; \ - (handler)(argv); \ - } \ - } while (0) - -// Poll for events until a condition or timeout -#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \ - do { \ - int64_t remaining = timeout; \ - uint64_t before = (remaining > 0) ? os_hrtime() : 0; \ - while (!(condition)) { \ - LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \ - if (remaining == 0) { \ - break; \ - } else if (remaining > 0) { \ - uint64_t now = os_hrtime(); \ - remaining -= (int64_t)((now - before) / 1000000); \ - before = now; \ - if (remaining <= 0) { \ - break; \ - } \ - } \ - } \ - } while (0) - -#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \ - do { \ - if (multiqueue && !multiqueue_empty(multiqueue)) { \ - multiqueue_process_events(multiqueue); \ - } else { \ - loop_poll_events(loop, timeout); \ - } \ - } while (0) - -struct signal_watcher; - typedef struct signal_watcher SignalWatcher; typedef void (*signal_cb)(SignalWatcher *watcher, int signum, void *data); typedef void (*signal_close_cb)(SignalWatcher *watcher, void *data); @@ -78,8 +32,6 @@ struct signal_watcher { MultiQueue *events; }; -struct time_watcher; - typedef struct time_watcher TimeWatcher; typedef void (*time_cb)(TimeWatcher *watcher, void *data); @@ -91,8 +43,6 @@ struct time_watcher { bool blockable; }; -struct wbuffer; - typedef struct wbuffer WBuffer; typedef void (*wbuffer_data_finalizer)(void *data); @@ -102,8 +52,6 @@ struct wbuffer { wbuffer_data_finalizer cb; }; -struct stream; - typedef struct stream Stream; /// Type of function called when the Stream buffer is filled with data /// @@ -151,8 +99,6 @@ struct stream { MultiQueue *events; }; -struct socket_watcher; - #define ADDRESS_MAX_SIZE 256 typedef struct socket_watcher SocketWatcher; diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index 07c059423a..65132ec2b1 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -4,8 +4,8 @@ #include #include "nvim/eval/typval.h" -#include "nvim/event/defs.h" #include "nvim/event/libuv_process.h" +#include "nvim/event/loop.h" #include "nvim/event/process.h" #include "nvim/log.h" #include "nvim/os/os.h" diff --git a/src/nvim/event/libuv_process.h b/src/nvim/event/libuv_process.h index e3e2bfeb76..3951bb6802 100644 --- a/src/nvim/event/libuv_process.h +++ b/src/nvim/event/libuv_process.h @@ -2,8 +2,8 @@ #include -#include "nvim/event/loop.h" #include "nvim/event/process.h" +#include "nvim/types_defs.h" typedef struct libuv_process { Process process; diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index a2cb72771c..93948d3eaa 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -3,12 +3,12 @@ #include #include -#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/log.h" #include "nvim/memory.h" #include "nvim/os/time.h" +#include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/loop.c.generated.h" diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index b567df5456..adcde4c909 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -1,19 +1,18 @@ #pragma once #include -#include #include #include "klib/klist.h" -#include "nvim/event/multiqueue.h" -#include "nvim/os/time.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep typedef void *WatcherPtr; #define _NOOP(x) KLIST_INIT(WatcherPtr, WatcherPtr, _NOOP) -typedef struct loop { +struct loop { uv_loop_t uv; MultiQueue *events; MultiQueue *thread_events; @@ -42,7 +41,7 @@ typedef struct loop { uv_mutex_t mutex; int recursive; bool closing; ///< Set to true if loop_close() has been called -} Loop; +}; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/loop.h.generated.h" diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index 26e3bc1c30..a0cebcea1d 100644 --- a/src/nvim/event/multiqueue.h +++ b/src/nvim/event/multiqueue.h @@ -2,8 +2,53 @@ #include // IWYU pragma: keep -#include "nvim/event/defs.h" // IWYU pragma: keep +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/os/time.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.h.generated.h" #endif + +#define multiqueue_put(q, h, ...) \ + do { \ + multiqueue_put_event(q, event_create(h, __VA_ARGS__)); \ + } while (0) + +#define CREATE_EVENT(multiqueue, handler, ...) \ + do { \ + if (multiqueue) { \ + multiqueue_put((multiqueue), (handler), __VA_ARGS__); \ + } else { \ + void *argv[] = { __VA_ARGS__ }; \ + (handler)(argv); \ + } \ + } while (0) + +// Poll for events until a condition or timeout +#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \ + do { \ + int64_t remaining = timeout; \ + uint64_t before = (remaining > 0) ? os_hrtime() : 0; \ + while (!(condition)) { \ + LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \ + if (remaining == 0) { \ + break; \ + } else if (remaining > 0) { \ + uint64_t now = os_hrtime(); \ + remaining -= (int64_t)((now - before) / 1000000); \ + before = now; \ + if (remaining <= 0) { \ + break; \ + } \ + } \ + } \ + } while (0) + +#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \ + do { \ + if (multiqueue && !multiqueue_empty(multiqueue)) { \ + multiqueue_process_events(multiqueue); \ + } else { \ + loop_poll_events(loop, timeout); \ + } \ + } while (0) diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 234fc815af..a18414a86a 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -5,13 +5,8 @@ #include #include "nvim/eval/typval_defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/multiqueue.h" -#include "nvim/event/rstream.h" -#include "nvim/event/stream.h" -#include "nvim/event/wstream.h" - -struct process; +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" typedef enum { kProcessTypeUv, diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index df97b592e4..c70ddeefb0 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -2,11 +2,9 @@ #include #include #include -#include #include -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" #include "nvim/event/stream.h" #include "nvim/log.h" @@ -14,6 +12,7 @@ #include "nvim/main.h" #include "nvim/os/os_defs.h" #include "nvim/rbuffer.h" +#include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/rstream.c.generated.h" diff --git a/src/nvim/event/rstream.h b/src/nvim/event/rstream.h index b2a62acf83..3b04e5d435 100644 --- a/src/nvim/event/rstream.h +++ b/src/nvim/event/rstream.h @@ -1,11 +1,7 @@ #pragma once -#include -#include -#include - -#include "nvim/event/loop.h" -#include "nvim/event/stream.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/rstream.h.generated.h" diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index 3a100812cf..57241e79b2 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -3,7 +3,9 @@ #include "nvim/event/defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/signal.h" +#include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/signal.c.generated.h" diff --git a/src/nvim/event/signal.h b/src/nvim/event/signal.h index 711797ca71..79784f1226 100644 --- a/src/nvim/event/signal.h +++ b/src/nvim/event/signal.h @@ -1,10 +1,7 @@ #pragma once -#include - -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/multiqueue.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/signal.h.generated.h" diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 3c7b98bfe7..35db9150b3 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -9,6 +9,7 @@ #include "nvim/charset.h" #include "nvim/event/defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/socket.h" #include "nvim/event/stream.h" #include "nvim/gettext.h" @@ -18,6 +19,7 @@ #include "nvim/os/fs.h" #include "nvim/os/os.h" #include "nvim/path.h" +#include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/socket.c.generated.h" diff --git a/src/nvim/event/socket.h b/src/nvim/event/socket.h index 24ba361efa..8dd72234d2 100644 --- a/src/nvim/event/socket.h +++ b/src/nvim/event/socket.h @@ -1,12 +1,7 @@ #pragma once -#include - -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/multiqueue.h" -#include "nvim/event/rstream.h" -#include "nvim/event/wstream.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/socket.h.generated.h" diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 886e93931b..0b9ed4f25b 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -9,6 +9,7 @@ #include "nvim/event/stream.h" #include "nvim/log.h" #include "nvim/rbuffer.h" +#include "nvim/types_defs.h" #ifdef MSWIN # include "nvim/os/os_win_console.h" #endif diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index 588aab12b0..f79c0ebaa3 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -1,13 +1,7 @@ #pragma once -#include -#include -#include - -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/multiqueue.h" -#include "nvim/rbuffer_defs.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/stream.h.generated.h" diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index de837fd278..861b15f6dd 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -6,6 +6,7 @@ #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/time.h" +#include "nvim/types_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/time.c.generated.h" diff --git a/src/nvim/event/time.h b/src/nvim/event/time.h index 85171f315a..0b684db897 100644 --- a/src/nvim/event/time.h +++ b/src/nvim/event/time.h @@ -1,11 +1,7 @@ #pragma once -#include -#include - -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/multiqueue.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/time.h.generated.h" diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index 70cc5b6547..406ff1620d 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -4,11 +4,11 @@ #include #include "nvim/event/defs.h" -#include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/event/wstream.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" +#include "nvim/types_defs.h" #define DEFAULT_MAXMEM 1024 * 1024 * 2000 diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h index d61ab644f4..5994e6d700 100644 --- a/src/nvim/event/wstream.h +++ b/src/nvim/event/wstream.h @@ -1,13 +1,7 @@ #pragma once -#include -#include -#include -#include - -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/stream.h" +#include "nvim/event/defs.h" // IWYU pragma: export +#include "nvim/types_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/wstream.h.generated.h" diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index c268f47323..70c8dc9019 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include "auto/config.h" #include "nvim/arglist.h" @@ -29,7 +29,8 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 974115d803..61e11636ae 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -11,7 +11,6 @@ #include "klib/kvec.h" #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" #include "nvim/arabic.h" diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 47f92920eb..82e3fe09d2 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -25,6 +25,7 @@ #include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/mapping.h" +#include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" diff --git a/src/nvim/fold.c b/src/nvim/fold.c index a268070dec..b595bb0f87 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -11,7 +11,6 @@ #include "klib/kvec.h" #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" diff --git a/src/nvim/garray.h b/src/nvim/garray.h index a96deda759..dd355984b3 100644 --- a/src/nvim/garray.h +++ b/src/nvim/garray.h @@ -6,7 +6,6 @@ #include "nvim/garray_defs.h" // IWYU pragma: export #include "nvim/log.h" #include "nvim/memory.h" -#include "nvim/types_defs.h" #define GA_EMPTY(ga_ptr) ((ga_ptr)->ga_len <= 0) diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 305b18fc28..5d6a220ec7 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -11,7 +11,6 @@ #include #include -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" @@ -22,6 +21,7 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_defs.h" +#include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" @@ -34,7 +34,6 @@ #include "nvim/insexpand.h" #include "nvim/keycodes.h" #include "nvim/lua/executor.h" -#include "nvim/macros_defs.h" #include "nvim/main.h" #include "nvim/mapping.h" #include "nvim/mbyte.h" diff --git a/src/nvim/grid.h b/src/nvim/grid.h index 9d8e395dae..7398ae7847 100644 --- a/src/nvim/grid.h +++ b/src/nvim/grid.h @@ -2,13 +2,12 @@ #include #include // IWYU pragma: keep -#include -#include "nvim/buffer_defs.h" #include "nvim/grid_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" #include "nvim/mbyte.h" #include "nvim/pos_defs.h" +#include "nvim/types_defs.h" /// By default, all windows are drawn on a single rectangular grid, represented by /// this ScreenGrid instance. In multigrid mode each window will have its own diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h index ea8a663a9f..228d96ceb2 100644 --- a/src/nvim/highlight.h +++ b/src/nvim/highlight.h @@ -2,7 +2,7 @@ #include -#include "nvim/api/keysets_defs.h" +#include "nvim/api/keysets_defs.h" // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" // IWYU pragma: export diff --git a/src/nvim/input.c b/src/nvim/input.c index a2a9692cb4..af66cfdcba 100644 --- a/src/nvim/input.c +++ b/src/nvim/input.c @@ -7,7 +7,6 @@ #include #include "nvim/ascii_defs.h" -#include "nvim/event/defs.h" #include "nvim/getchar.h" #include "nvim/gettext.h" #include "nvim/globals.h" diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index f8475b3e22..301c3846e7 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "nvim/ascii_defs.h" #include "nvim/charset.h" diff --git a/src/nvim/keycodes.h b/src/nvim/keycodes.h index db9ef38cc3..fafe205f4d 100644 --- a/src/nvim/keycodes.h +++ b/src/nvim/keycodes.h @@ -3,9 +3,8 @@ #include #include "nvim/ascii_defs.h" -#include "nvim/option_defs.h" +#include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/option_vars.h" -#include "nvim/strings.h" // Keycode definitions for special keys. // diff --git a/src/nvim/log.h b/src/nvim/log.h index c6a033c634..1fb15e3503 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -1,7 +1,9 @@ #pragma once +#include +#include + #include "auto/config.h" -#include "nvim/log_defs.h" // IWYU pragma: export #include "nvim/macros_defs.h" // USDT probes. Example invocation: @@ -20,6 +22,35 @@ #endif // uncrustify:on +#define LOGLVL_DBG 1 +#define LOGLVL_INF 2 +#define LOGLVL_WRN 3 +#define LOGLVL_ERR 4 + +#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, __VA_ARGS__) + +#ifdef NVIM_LOG_DEBUG +# define DLOG(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, true, __VA_ARGS__) +# define DLOGN(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, false, __VA_ARGS__) +# define ILOG(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, true, __VA_ARGS__) +# define ILOGN(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, false, __VA_ARGS__) +#else +# define DLOG(...) +# define DLOGN(...) +# define ILOG(...) +# define ILOGN(...) +#endif + +#define WLOG(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, true, __VA_ARGS__) +#define WLOGN(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, false, __VA_ARGS__) +#define ELOG(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, true, __VA_ARGS__) +#define ELOGN(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, false, __VA_ARGS__) + +#ifdef HAVE_EXECINFO_BACKTRACE +# define LOG_CALLSTACK() log_callstack(__func__, __LINE__) +# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) +#endif + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "log.h.generated.h" #endif diff --git a/src/nvim/log_defs.h b/src/nvim/log_defs.h deleted file mode 100644 index 1b666720fc..0000000000 --- a/src/nvim/log_defs.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -#include "auto/config.h" -#include "nvim/macros_defs.h" - -#define LOGLVL_DBG 1 -#define LOGLVL_INF 2 -#define LOGLVL_WRN 3 -#define LOGLVL_ERR 4 - -#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, __VA_ARGS__) - -#ifdef NVIM_LOG_DEBUG -# define DLOG(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, true, __VA_ARGS__) -# define DLOGN(...) logmsg(LOGLVL_DBG, NULL, __func__, __LINE__, false, __VA_ARGS__) -# define ILOG(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, true, __VA_ARGS__) -# define ILOGN(...) logmsg(LOGLVL_INF, NULL, __func__, __LINE__, false, __VA_ARGS__) -#else -# define DLOG(...) -# define DLOGN(...) -# define ILOG(...) -# define ILOGN(...) -#endif - -#define WLOG(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, true, __VA_ARGS__) -#define WLOGN(...) logmsg(LOGLVL_WRN, NULL, __func__, __LINE__, false, __VA_ARGS__) -#define ELOG(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, true, __VA_ARGS__) -#define ELOGN(...) logmsg(LOGLVL_ERR, NULL, __func__, __LINE__, false, __VA_ARGS__) - -#ifdef HAVE_EXECINFO_BACKTRACE -# define LOG_CALLSTACK() log_callstack(__func__, __LINE__) -# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__) -#endif diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 43a6a12fda..3e7cdd002e 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -13,7 +13,6 @@ #include "klib/kvec.h" #include "luv/luv.h" #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" @@ -24,10 +23,9 @@ #include "nvim/eval.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/eval/userfunc.h" -#include "nvim/event/defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/time.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index b38faddbb3..0b4623cbd3 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -4,18 +4,13 @@ #include #include -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" -#include "nvim/assert_defs.h" -#include "nvim/cmdexpand_defs.h" -#include "nvim/eval/typval_defs.h" -#include "nvim/ex_cmds_defs.h" +#include "nvim/cmdexpand_defs.h" // IWYU pragma: keep +#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/func_attr.h" -#include "nvim/lua/converter.h" #include "nvim/macros_defs.h" -#include "nvim/map_defs.h" #include "nvim/types_defs.h" -#include "nvim/usercmd.h" +#include "nvim/usercmd.h" // IWYU pragma: keep // Generated by msgpack-gen.lua void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL; diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 4b7d2dab21..db710457c3 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #ifdef NVIM_VENDOR_BIT # include "bit.h" @@ -14,7 +14,6 @@ #include "cjson/lua_cjson.h" #include "mpack/lmpack.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" diff --git a/src/nvim/lua/xdiff.c b/src/nvim/lua/xdiff.c index 5285c1187d..e21bca170f 100644 --- a/src/nvim/lua/xdiff.c +++ b/src/nvim/lua/xdiff.c @@ -5,7 +5,6 @@ #include #include "luaconf.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/linematch.h" #include "nvim/lua/converter.h" diff --git a/src/nvim/macros_defs.h b/src/nvim/macros_defs.h index a7af2f91c3..a0dcafab95 100644 --- a/src/nvim/macros_defs.h +++ b/src/nvim/macros_defs.h @@ -29,9 +29,6 @@ /// @return `s, sizeof(s) - 1` #define S_LEN(s) (s), (sizeof(s) - 1) -/// LINEEMPTY() - return true if the line is empty -#define LINEEMPTY(p) (*ml_get(p) == 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. @@ -54,48 +51,12 @@ // Returns empty string if it is NULL. #define EMPTY_IF_NULL(x) ((x) ? (x) : "") -/// Adjust chars in a language according to 'langmap' option. -/// NOTE that there is no noticeable overhead if 'langmap' is not set. -/// When set the overhead for characters < 256 is small. -/// Don't apply 'langmap' if the character comes from the Stuff buffer or from a -/// mapping and the langnoremap option was set. -/// The do-while is just to ignore a ';' after the macro. -#define LANGMAP_ADJUST(c, condition) \ - do { \ - if (*p_langmap \ - && (condition) \ - && (p_lrm || (vgetc_busy ? typebuf_maplen() == 0 : KeyTyped)) \ - && !KeyStuffed \ - && (c) >= 0) \ - { \ - if ((c) < 256) \ - c = langmap_mapchar[c]; \ - else \ - c = langmap_adjust_mb(c); \ - } \ - } while (0) - #define WRITEBIN "wb" // no CR-LF translation #define READBIN "rb" #define APPENDBIN "ab" #define REPLACE_NORMAL(s) (((s)& REPLACE_FLAG) && !((s)& VREPLACE_FLAG)) -// MB_PTR_ADV(): advance a pointer to the next character, taking care of -// multi-byte characters if needed. Skip over composing chars. -#define MB_PTR_ADV(p) (p += utfc_ptr2len((char *)p)) - -// Advance multi-byte pointer, do not skip over composing chars. -#define MB_CPTR_ADV(p) (p += utf_ptr2len((char *)p)) - -// MB_PTR_BACK(): backup a pointer to the previous character, taking care of -// multi-byte characters if needed. Only use with "p" > "s" ! -#define MB_PTR_BACK(s, p) \ - (p -= utf_head_off((char *)(s), (char *)(p) - 1) + 1) - -// MB_CHAR2BYTES(): convert character to bytes and advance pointer to bytes -#define MB_CHAR2BYTES(c, b) ((b) += utf_char2bytes((c), ((char *)b))) - #define RESET_BINDING(wp) \ do { \ (wp)->w_p_scb = false; \ diff --git a/src/nvim/main.c b/src/nvim/main.c index bf0b8d33b2..dfa7c685a0 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -19,7 +19,6 @@ #include "auto/config.h" // IWYU pragma: keep #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/ui.h" #include "nvim/arglist.h" diff --git a/src/nvim/main.h b/src/nvim/main.h index 6aeb62712a..dedfadf270 100644 --- a/src/nvim/main.h +++ b/src/nvim/main.h @@ -3,6 +3,7 @@ #include #include "nvim/event/loop.h" +#include "nvim/types_defs.h" // Maximum number of commands from + or -c arguments. #define MAX_ARG_CMDS 10 diff --git a/src/nvim/map_glyph_cache.c b/src/nvim/map_glyph_cache.c index 5efa87b960..091b4f7990 100644 --- a/src/nvim/map_glyph_cache.c +++ b/src/nvim/map_glyph_cache.c @@ -11,7 +11,6 @@ #include #include -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/mapping.h b/src/nvim/mapping.h index ffe7ab4290..3baa52ee77 100644 --- a/src/nvim/mapping.h +++ b/src/nvim/mapping.h @@ -13,6 +13,10 @@ #include "nvim/regexp_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "mapping.h.generated.h" +#endif + /// Used for the first argument of do_map() enum { MAPTYPE_MAP = 0, @@ -20,6 +24,23 @@ enum { MAPTYPE_NOREMAP = 2, }; -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "mapping.h.generated.h" -#endif +/// Adjust chars in a language according to 'langmap' option. +/// NOTE that there is no noticeable overhead if 'langmap' is not set. +/// When set the overhead for characters < 256 is small. +/// Don't apply 'langmap' if the character comes from the Stuff buffer or from a +/// mapping and the langnoremap option was set. +/// The do-while is just to ignore a ';' after the macro. +#define LANGMAP_ADJUST(c, condition) \ + do { \ + if (*p_langmap \ + && (condition) \ + && (p_lrm || (vgetc_busy ? typebuf_maplen() == 0 : KeyTyped)) \ + && !KeyStuffed \ + && (c) >= 0) \ + { \ + if ((c) < 256) \ + c = langmap_mapchar[c]; \ + else \ + c = langmap_adjust_mb(c); \ + } \ + } while (0) diff --git a/src/nvim/mark.h b/src/nvim/mark.h index ec6862b38f..2c1bf7c73c 100644 --- a/src/nvim/mark.h +++ b/src/nvim/mark.h @@ -1,15 +1,21 @@ #pragma once +#include + #include "nvim/ascii_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/extmark_defs.h" // IWYU pragma: keep #include "nvim/func_attr.h" #include "nvim/macros_defs.h" #include "nvim/mark_defs.h" // IWYU pragma: export +#include "nvim/os/time.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "mark.h.generated.h" +#endif static inline int mark_global_index(char name) REAL_FATTR_CONST; - /// Convert mark name to the offset static inline int mark_global_index(const char name) { @@ -22,7 +28,6 @@ static inline int mark_global_index(const char name) static inline int mark_local_index(char name) REAL_FATTR_CONST; - /// Convert local mark name to the offset static inline int mark_local_index(const char name) { @@ -40,6 +45,37 @@ static inline int mark_local_index(const char name) /// Global marks (marks with file number or name) EXTERN xfmark_T namedfm[NGLOBALMARKS] INIT( = { 0 }); -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "mark.h.generated.h" -#endif +#define SET_FMARK(fmarkp_, mark_, fnum_, view_) \ + do { \ + fmark_T *const fmarkp__ = fmarkp_; \ + fmarkp__->mark = mark_; \ + fmarkp__->fnum = fnum_; \ + fmarkp__->timestamp = os_time(); \ + fmarkp__->view = view_; \ + fmarkp__->additional_data = NULL; \ + } while (0) + +/// Free and set fmark using given value +#define RESET_FMARK(fmarkp_, mark_, fnum_, view_) \ + do { \ + fmark_T *const fmarkp___ = fmarkp_; \ + free_fmark(*fmarkp___); \ + SET_FMARK(fmarkp___, mark_, fnum_, view_); \ + } while (0) + +/// Set given extended mark (regular mark + file name) +#define SET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ + do { \ + xfmark_T *const xfmarkp__ = xfmarkp_; \ + xfmarkp__->fname = fname_; \ + SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ + } while (0) + +/// Free and set given extended mark (regular mark + file name) +#define RESET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ + do { \ + xfmark_T *const xfmarkp__ = xfmarkp_; \ + free_xfmark(*xfmarkp__); \ + xfmarkp__->fname = fname_; \ + SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ + } while (0) diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h index a98a741363..5028781827 100644 --- a/src/nvim/mark_defs.h +++ b/src/nvim/mark_defs.h @@ -86,41 +86,6 @@ typedef struct xfilemark { #define INIT_XFMARK { INIT_FMARK, NULL } /// Set fmark using given value -#define SET_FMARK(fmarkp_, mark_, fnum_, view_) \ - do { \ - fmark_T *const fmarkp__ = fmarkp_; \ - fmarkp__->mark = mark_; \ - fmarkp__->fnum = fnum_; \ - fmarkp__->timestamp = os_time(); \ - fmarkp__->view = view_; \ - fmarkp__->additional_data = NULL; \ - } while (0) - -/// Free and set fmark using given value -#define RESET_FMARK(fmarkp_, mark_, fnum_, view_) \ - do { \ - fmark_T *const fmarkp___ = fmarkp_; \ - free_fmark(*fmarkp___); \ - SET_FMARK(fmarkp___, mark_, fnum_, view_); \ - } while (0) - -/// Set given extended mark (regular mark + file name) -#define SET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ - do { \ - xfmark_T *const xfmarkp__ = xfmarkp_; \ - xfmarkp__->fname = fname_; \ - SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ - } while (0) - -/// Free and set given extended mark (regular mark + file name) -#define RESET_XFMARK(xfmarkp_, mark_, fnum_, view_, fname_) \ - do { \ - xfmark_T *const xfmarkp__ = xfmarkp_; \ - free_xfmark(*xfmarkp__); \ - xfmarkp__->fname = fname_; \ - SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_, view_); \ - } while (0) - static inline bool lt(pos_T a, pos_T b) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE; /// Return true if position a is before (less than) position b. diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index 958970bba1..fb0d0502ee 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include "klib/kvec.h" #include "nvim/macros_defs.h" diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index a992bf3cd8..b788d7aa6f 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include "auto/config.h" diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index bae60185e2..96f8b24983 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -4,6 +4,7 @@ #include #include #include // IWYU pragma: keep +#include // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" // IWYU pragma: keep @@ -11,6 +12,10 @@ #include "nvim/mbyte_defs.h" // IWYU pragma: export #include "nvim/types_defs.h" // IWYU pragma: keep +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "mbyte.h.generated.h" +#endif + // Return byte length of character that starts with byte "b". // Returns 1 for a single-byte character. // MB_BYTE2LEN_CHECK() can be used to count a special key as one byte. @@ -22,13 +27,8 @@ extern const uint8_t utf8len_tab_zero[256]; extern const uint8_t utf8len_tab[256]; -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "mbyte.h.generated.h" -#endif - static inline int mb_strcmp_ic(bool ic, const char *s1, const char *s2) REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; - /// Compare strings /// /// @param[in] ic True if case is to be ignored. @@ -38,3 +38,24 @@ static inline int mb_strcmp_ic(bool ic, const char *s1, const char *s2) { return (ic ? mb_stricmp(s1, s2) : strcmp(s1, s2)); } + +// Use our own character-case definitions, because the current locale may +// differ from what the .spl file uses. +// These must not be called with negative number! +// Multi-byte implementation. For Unicode we can call utf_*(), but don't do +// that for ASCII, because we don't want to use 'casemap' here. Otherwise use +// the "w" library function for characters above 255. +#define SPELL_TOFOLD(c) ((c) >= 128 ? utf_fold(c) : (int)spelltab.st_fold[c]) + +#define SPELL_TOUPPER(c) ((c) >= 128 ? mb_toupper(c) : (int)spelltab.st_upper[c]) + +#define SPELL_ISUPPER(c) ((c) >= 128 ? mb_isupper(c) : spelltab.st_isu[c]) + +// MB_PTR_ADV(): advance a pointer to the next character, taking care of +// multi-byte characters if needed. Skip over composing chars. +#define MB_PTR_ADV(p) (p += utfc_ptr2len((char *)p)) + +// MB_PTR_BACK(): backup a pointer to the previous character, taking care of +// multi-byte characters if needed. Only use with "p" > "s" ! +#define MB_PTR_BACK(s, p) \ + (p -= utf_head_off((char *)(s), (char *)(p) - 1) + 1) diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 63f3541b3c..8f6b78d2d5 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include diff --git a/src/nvim/memline.h b/src/nvim/memline.h index 808d97783e..8e7f3a565c 100644 --- a/src/nvim/memline.h +++ b/src/nvim/memline.h @@ -1,5 +1,6 @@ #pragma once +#include "nvim/ascii_defs.h" #include "nvim/eval/typval_defs.h" // IWYU pragma: keep #include "nvim/memline_defs.h" // IWYU pragma: export #include "nvim/pos_defs.h" // IWYU pragma: keep @@ -8,3 +9,6 @@ #ifdef INCLUDE_GENERATED_DECLARATIONS # include "memline.h.generated.h" #endif + +/// LINEEMPTY() - return true if the line is empty +#define LINEEMPTY(p) (*ml_get(p) == NUL) diff --git a/src/nvim/message.c b/src/nvim/message.c index 38952d2cf6..895fba1372 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -8,10 +8,9 @@ #include #include #include -#include +#include #include "klib/kvec.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" @@ -20,7 +19,6 @@ #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" -#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index c9139f5f93..f1b7f8026e 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -15,6 +15,7 @@ #include "nvim/api/ui.h" #include "nvim/channel.h" #include "nvim/event/defs.h" +#include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/process.h" #include "nvim/event/rstream.h" diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h index dd2096f305..6344d8c567 100644 --- a/src/nvim/msgpack_rpc/helpers.h +++ b/src/nvim/msgpack_rpc/helpers.h @@ -1,11 +1,8 @@ #pragma once -#include -#include -#include +#include // IWYU pragma: keep #include "nvim/api/private/defs.h" -#include "nvim/event/wstream.h" /// Value by which objects represented as EXT type are shifted /// diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c index 0cc249b2b8..e60c1b88a5 100644 --- a/src/nvim/msgpack_rpc/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -6,7 +6,6 @@ #include "nvim/channel.h" #include "nvim/eval.h" -#include "nvim/event/defs.h" #include "nvim/event/socket.h" #include "nvim/garray.h" #include "nvim/log.h" diff --git a/src/nvim/msgpack_rpc/unpacker.h b/src/nvim/msgpack_rpc/unpacker.h index 53af29761e..d43dc2e997 100644 --- a/src/nvim/msgpack_rpc/unpacker.h +++ b/src/nvim/msgpack_rpc/unpacker.h @@ -1,17 +1,14 @@ #pragma once #include -#include #include #include "mpack/mpack_core.h" #include "mpack/object.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" -#include "nvim/api/private/helpers.h" #include "nvim/grid_defs.h" #include "nvim/memory_defs.h" -#include "nvim/msgpack_rpc/channel_defs.h" +#include "nvim/msgpack_rpc/channel_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" #include "nvim/ui_client.h" diff --git a/src/nvim/ops.c b/src/nvim/ops.c index ece7ccc960..d0a6b2c074 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include "nvim/api/private/defs.h" #include "nvim/ascii_defs.h" diff --git a/src/nvim/option.h b/src/nvim/option.h index 2e4186fe7f..9dbb176c94 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -1,14 +1,17 @@ #pragma once #include +#include #include #include // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep #include "nvim/api/private/helpers.h" +#include "nvim/assert_defs.h" #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep +#include "nvim/macros_defs.h" #include "nvim/math.h" #include "nvim/option_defs.h" // IWYU pragma: export #include "nvim/types_defs.h" // IWYU pragma: keep diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 8765fdea4f..0aa11beb6d 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -9,7 +9,6 @@ #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" -#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h index 4b104b0b50..abef46072b 100644 --- a/src/nvim/os/input.h +++ b/src/nvim/os/input.h @@ -4,7 +4,7 @@ #include // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep -#include "nvim/event/multiqueue.h" +#include "nvim/event/defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" EXTERN bool used_stdin INIT( = false); diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 4478d9d7bd..1bdbb094bd 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -32,7 +32,6 @@ #include "auto/config.h" #include "klib/klist.h" #include "nvim/eval/typval.h" -#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/process.h" #include "nvim/log.h" diff --git a/src/nvim/os/pty_process_unix.h b/src/nvim/os/pty_process_unix.h index 92cc582832..c04e4c7a20 100644 --- a/src/nvim/os/pty_process_unix.h +++ b/src/nvim/os/pty_process_unix.h @@ -4,8 +4,8 @@ #include #include -#include "nvim/event/loop.h" #include "nvim/event/process.h" +#include "nvim/types_defs.h" typedef struct pty_process { Process process; diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 563a79358c..e898879729 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,6 +4,7 @@ #include "nvim/ascii_defs.h" #include "nvim/eval/typval.h" +#include "nvim/event/loop.h" #include "nvim/log.h" #include "nvim/mbyte.h" #include "nvim/memory.h" diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 26c202741a..aa5075a79b 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -12,7 +12,6 @@ #include "nvim/charset.h" #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" -#include "nvim/event/defs.h" #include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 0b0e59946c..0cbedc7330 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -9,7 +9,6 @@ #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" #include "nvim/eval.h" -#include "nvim/event/defs.h" #include "nvim/event/signal.h" #include "nvim/globals.h" #include "nvim/log.h" diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index f842bb0ab8..b2a402f559 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -7,7 +7,8 @@ #include #include "auto/config.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/log.h" diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index df82cb259e..bb4cad0b54 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -6,7 +6,6 @@ #include #include -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" #include "nvim/ascii_defs.h" diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 20c06340be..87f28a4379 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" @@ -6379,7 +6379,7 @@ static bool regmatch(uint8_t *scan, const proftime_T *tm, int *timed_out) case RE_COMPOSING: // Skip composing characters. while (utf_iscomposing(utf_ptr2char((char *)rex.input))) { - MB_CPTR_ADV(rex.input); + rex.input += utf_ptr2len((char *)rex.input); } break; @@ -9840,7 +9840,7 @@ static int nfa_regatom(void) emsg(_(e_nopresub)); return FAIL; } - for (lp = (uint8_t *)reg_prev_sub; *lp != NUL; MB_CPTR_ADV(lp)) { + for (lp = (uint8_t *)reg_prev_sub; *lp != NUL; lp += utf_ptr2len((char *)lp)) { EMIT(utf_ptr2char((char *)lp)); if (lp != (uint8_t *)reg_prev_sub) { EMIT(NFA_CONCAT); diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 5c479bb1c6..09142e55e0 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -13,7 +13,6 @@ #include #include "auto/config.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer.h" diff --git a/src/nvim/sign.c b/src/nvim/sign.c index b52142f721..0647d65e93 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -9,7 +9,6 @@ #include "klib/kvec.h" #include "nvim/api/extmark.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer.h" diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index 6293bc314b..37048451a2 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -216,18 +216,6 @@ typedef struct { uint8_t st_upper[256]; ///< chars: upper case } spelltab_T; -// Use our own character-case definitions, because the current locale may -// differ from what the .spl file uses. -// These must not be called with negative number! -// Multi-byte implementation. For Unicode we can call utf_*(), but don't do -// that for ASCII, because we don't want to use 'casemap' here. Otherwise use -// the "w" library function for characters above 255. -#define SPELL_TOFOLD(c) ((c) >= 128 ? utf_fold(c) : (int)spelltab.st_fold[c]) - -#define SPELL_TOUPPER(c) ((c) >= 128 ? mb_toupper(c) : (int)spelltab.st_upper[c]) - -#define SPELL_ISUPPER(c) ((c) >= 128 ? mb_isupper(c) : spelltab.st_isu[c]) - /// Values for "what" argument of spell_add_word() typedef enum { SPELL_ADD_GOOD = 0, diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 979495e810..0cffd5741e 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -1536,7 +1536,7 @@ static int set_sofo(slang_T *lp, const char *from, const char *to) // sl_sal_first[] for this. for (p = from, s = to; *p != NUL && *s != NUL;) { const int c = mb_cptr2char_adv(&p); - MB_CPTR_ADV(s); + s += utf_ptr2len(s); if (c >= 256) { lp->sl_sal_first[c & 0xff]++; } diff --git a/src/nvim/state.c b/src/nvim/state.c index 518ceb8c88..d04c131226 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -7,7 +7,7 @@ #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/ex_getln.h" #include "nvim/getchar.h" diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 01729bc4de..112a433d9d 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -6,7 +6,6 @@ #include #include -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer.h" @@ -1178,7 +1177,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op out_p = out_p - n + 1; // Fill up space left over by half a double-wide char. while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) { - MB_CHAR2BYTES(fillchar, out_p); + out_p += utf_char2bytes(fillchar, out_p); } // } @@ -1201,7 +1200,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op if (min_group_width < 0) { min_group_width = 0 - min_group_width; while (group_len++ < min_group_width && out_p < out_end_p) { - MB_CHAR2BYTES(fillchar, out_p); + out_p += utf_char2bytes(fillchar, out_p); } // If the group is right-aligned, shift everything to the right and // prepend with filler characters. @@ -1222,7 +1221,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // Prepend the fill characters for (; group_len > 0; group_len--) { - MB_CHAR2BYTES(fillchar, t); + t += utf_char2bytes(fillchar, t); } } } @@ -1803,7 +1802,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op if (l + 1 == minwid && fillchar == '-' && ascii_isdigit(*t)) { *out_p++ = ' '; } else { - MB_CHAR2BYTES(fillchar, out_p); + out_p += utf_char2bytes(fillchar, out_p); } } minwid = 0; @@ -1826,7 +1825,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // digit follows. if (fillable && *t == ' ' && (!ascii_isdigit(*(t + 1)) || fillchar != '-')) { - MB_CHAR2BYTES(fillchar, out_p); + out_p += utf_char2bytes(fillchar, out_p); } else { *out_p++ = *t; } @@ -1843,7 +1842,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // For left-aligned items, fill any remaining space with the fillchar for (; l < minwid && out_p < out_end_p; l++) { - MB_CHAR2BYTES(fillchar, out_p); + out_p += utf_char2bytes(fillchar, out_p); } // Otherwise if the item is a number, copy that to the output buffer. @@ -2064,7 +2063,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // Fill up for half a double-wide character. while (++width < maxwidth) { - MB_CHAR2BYTES(fillchar, trunc_p); + trunc_p += utf_char2bytes(fillchar, trunc_p); *trunc_p = NUL; } } @@ -2099,7 +2098,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op char *seploc = start + dislocation; STRMOVE(seploc, start); for (char *s = start; s < seploc;) { - MB_CHAR2BYTES(fillchar, s); + s += utf_char2bytes(fillchar, s); } for (int item_idx = stl_separator_locations[l] + 1; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 1586dd3d8e..80e5d5b126 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -44,7 +44,6 @@ #include #include "klib/kvec.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" @@ -56,7 +55,7 @@ #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" #include "nvim/event/time.h" #include "nvim/ex_docmd.h" diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 1b9732c5b2..7803322439 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -18,7 +18,6 @@ #include "nvim/globals.h" #include "nvim/indent.h" #include "nvim/indent_c.h" -#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c index 9c601769c0..0cfbb50684 100644 --- a/src/nvim/textobject.c +++ b/src/nvim/textobject.c @@ -14,7 +14,6 @@ #include "nvim/fold.h" #include "nvim/globals.h" #include "nvim/indent.h" -#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 9ba21a6afd..c7880b591d 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -4,9 +4,8 @@ #include #include "klib/kvec.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/macros_defs.h" #include "nvim/main.h" diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index bc490754be..2da7f95338 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -4,7 +4,6 @@ #include #include -#include "nvim/event/loop.h" #include "nvim/event/stream.h" #include "nvim/rbuffer_defs.h" #include "nvim/tui/input_defs.h" // IWYU pragma: export diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 6c0b00f010..934b498df9 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -15,7 +15,6 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/cursor_shape.h" -#include "nvim/event/defs.h" #include "nvim/event/loop.h" #include "nvim/event/signal.h" #include "nvim/event/stream.h" diff --git a/src/nvim/types_defs.h b/src/nvim/types_defs.h index cc9deb9630..b2c7101f60 100644 --- a/src/nvim/types_defs.h +++ b/src/nvim/types_defs.h @@ -57,7 +57,8 @@ typedef struct { #define SIGNRANGE_INIT { 0, 0 } typedef struct file_buffer buf_T; +typedef struct loop Loop; +typedef struct regprog regprog_T; typedef struct syn_state synstate_T; typedef struct terminal Terminal; typedef struct window_S win_T; -typedef struct regprog regprog_T; diff --git a/src/nvim/ui.h b/src/nvim/ui.h index f61398a7a0..8b00e4e917 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -3,7 +3,7 @@ #include // IWYU pragma: keep #include "nvim/api/private/defs.h" // IWYU pragma: keep -#include "nvim/event/multiqueue.h" +#include "nvim/event/defs.h" #include "nvim/grid_defs.h" // IWYU pragma: keep #include "nvim/highlight_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c index fdd859ba29..c7c0457fcd 100644 --- a/src/nvim/ui_client.c +++ b/src/nvim/ui_client.c @@ -10,7 +10,7 @@ #include "nvim/channel.h" #include "nvim/eval.h" #include "nvim/eval/typval_defs.h" -#include "nvim/event/defs.h" +#include "nvim/event/multiqueue.h" #include "nvim/globals.h" #include "nvim/highlight.h" #include "nvim/log.h" diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index d8969b0061..4cd11f3ccf 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include "klib/kvec.h" #include "nvim/api/private/defs.h" diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 7c44f0de62..2d631f237f 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -77,7 +77,6 @@ #include #include #include -#include #include #include @@ -106,6 +105,7 @@ #include "nvim/highlight.h" #include "nvim/macros_defs.h" #include "nvim/mark.h" +#include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index 9872468ba9..86c0dc8367 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -8,7 +8,6 @@ #include #include "auto/config.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" diff --git a/src/nvim/usercmd.h b/src/nvim/usercmd.h index 4d6d154b79..4ad9767e1f 100644 --- a/src/nvim/usercmd.h +++ b/src/nvim/usercmd.h @@ -10,7 +10,7 @@ #include "nvim/garray_defs.h" #include "nvim/types_defs.h" // IWYU pragma: keep -typedef struct ucmd { +typedef struct { char *uc_name; ///< The command name uint32_t uc_argt; ///< The argument type char *uc_rep; ///< The command's replacement string diff --git a/src/nvim/version.c b/src/nvim/version.c index 2caf2c0cb8..814c8f5169 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -13,7 +13,6 @@ #include "auto/versiondef.h" // version info generated by the build system #include "auto/versiondef_git.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii_defs.h" #include "nvim/buffer.h" diff --git a/src/nvim/viml/parser/parser.h b/src/nvim/viml/parser/parser.h index cd5a493643..b29a77b5ef 100644 --- a/src/nvim/viml/parser/parser.h +++ b/src/nvim/viml/parser/parser.h @@ -7,7 +7,6 @@ #include "klib/kvec.h" #include "nvim/func_attr.h" #include "nvim/mbyte.h" -#include "nvim/mbyte_defs.h" #include "nvim/memory.h" /// One parsed line diff --git a/src/nvim/window.c b/src/nvim/window.c index 929a06350b..b140337fec 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -8,7 +8,6 @@ #include #include "klib/kvec.h" -#include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/arglist.h" #include "nvim/ascii_defs.h" -- cgit From 6700127b30d55e6ddf70495e7b886464172d7ac6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 22 Dec 2023 10:33:34 +0800 Subject: vim-patch:9.0.2183: Maximum callback depth is not configurable (#26703) Problem: Maximum callback depth is not configurable. Solution: Revert patch 9.0.2103. Set 'maxfuncdepth' in test. fixes: vim/vim#13732 closes: vim/vim#13736 https://github.com/vim/vim/commit/fe583b1e5987fbfdb5f2141c133dbff9665ed301 --- src/nvim/eval.c | 4 +--- src/nvim/options.lua | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 68347fd582..3818944fc9 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -89,8 +89,6 @@ #define DICT_MAXNEST 100 // maximum nesting of lists and dicts -#define MAX_CALLBACK_DEPTH 20 - static const char *e_missbrac = N_("E111: Missing ']'"); static const char *e_list_end = N_("E697: Missing end of List ']': %s"); static const char e_cannot_slice_dictionary[] @@ -6061,7 +6059,7 @@ bool callback_call(Callback *const callback, const int argcount_in, typval_T *co typval_T *const rettv) FUNC_ATTR_NONNULL_ALL { - if (callback_depth > MAX_CALLBACK_DEPTH) { + if (callback_depth > p_mfd) { emsg(_(e_command_too_recursive)); return false; } diff --git a/src/nvim/options.lua b/src/nvim/options.lua index cb25d481ec..43c938b0bf 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -5158,6 +5158,7 @@ return { Increasing this limit above 200 also changes the maximum for Ex command recursion, see |E169|. See also |:function|. + Also used for maximum depth of callback functions. ]=], full_name = 'maxfuncdepth', scope = { 'global' }, -- cgit From 089b934352437ab310a6dd3b138c7ed9445a3d7b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 22 Dec 2023 12:24:23 +0800 Subject: refactor(options): generate BV_ and WV_ constants (#26705) --- src/clint.py | 13 --- src/nvim/buffer_defs.h | 2 +- src/nvim/eval/userfunc.h | 2 - src/nvim/fold.c | 1 + src/nvim/generators/gen_options_enum.lua | 53 +++++++++++ src/nvim/globals.h | 3 +- src/nvim/input.h | 2 +- src/nvim/lua/executor.h | 1 + src/nvim/option_vars.h | 150 ------------------------------- src/nvim/viml/parser/expressions.h | 2 - 10 files changed, 58 insertions(+), 171 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 303c3df25d..663416553e 100755 --- a/src/clint.py +++ b/src/clint.py @@ -901,7 +901,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/api/private/validate.h", "src/nvim/assert_defs.h", "src/nvim/buffer.h", - "src/nvim/buffer_defs.h", "src/nvim/channel.h", "src/nvim/charset.h", "src/nvim/eval.h", @@ -910,34 +909,22 @@ def CheckIncludes(filename, lines, error): "src/nvim/eval/typval_defs.h", "src/nvim/eval/userfunc.h", "src/nvim/event/libuv_process.h", - "src/nvim/event/loop.h", "src/nvim/event/multiqueue.h", - "src/nvim/event/process.h", - "src/nvim/event/rstream.h", - "src/nvim/event/signal.h", - "src/nvim/event/socket.h", - "src/nvim/event/stream.h", - "src/nvim/event/time.h", - "src/nvim/event/wstream.h", "src/nvim/garray.h", "src/nvim/globals.h", "src/nvim/grid.h", "src/nvim/highlight.h", - "src/nvim/input.h", "src/nvim/keycodes.h", "src/nvim/lua/executor.h", "src/nvim/main.h", "src/nvim/mark.h", "src/nvim/msgpack_rpc/channel_defs.h", - "src/nvim/msgpack_rpc/helpers.h", "src/nvim/msgpack_rpc/unpacker.h", "src/nvim/option.h", - "src/nvim/os/input.h", "src/nvim/os/pty_conpty_win.h", "src/nvim/os/pty_process_unix.h", "src/nvim/os/pty_process_win.h", "src/nvim/tui/input.h", - "src/nvim/ui.h", "src/nvim/viml/parser/expressions.h", "src/nvim/viml/parser/parser.h", ] diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3a6b5e2c6b..ca6e874c1f 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -18,7 +18,7 @@ #include "nvim/mark_defs.h" #include "nvim/marktree_defs.h" #include "nvim/memline_defs.h" -#include "nvim/option_vars.h" +#include "nvim/option_defs.h" #include "nvim/os/fs_defs.h" #include "nvim/pos_defs.h" #include "nvim/regexp_defs.h" diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 65a96a13c5..270ca7db4e 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -11,8 +11,6 @@ #include "nvim/pos_defs.h" #include "nvim/types_defs.h" // IWYU pragma: keep -struct funccal_entry; - // From user function to hashitem and back. #define UF2HIKEY(fp) ((fp)->uf_name) #define HIKEY2UF(p) ((ufunc_T *)((p) - offsetof(ufunc_T, uf_name))) diff --git a/src/nvim/fold.c b/src/nvim/fold.c index b595bb0f87..3b7662e62d 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -38,6 +38,7 @@ #include "nvim/message.h" #include "nvim/move.h" #include "nvim/ops.h" +#include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/os/input.h" #include "nvim/plines.h" diff --git a/src/nvim/generators/gen_options_enum.lua b/src/nvim/generators/gen_options_enum.lua index c3fe9baae6..9a3953fcbc 100644 --- a/src/nvim/generators/gen_options_enum.lua +++ b/src/nvim/generators/gen_options_enum.lua @@ -1,5 +1,6 @@ -- Generates option index enum and map of option name to option index. -- Handles option full name, short name and aliases. +-- Also generates BV_ and WV_ enum constants. local options_enum_file = arg[1] local options_map_file = arg[2] @@ -16,6 +17,9 @@ local function map_w(s) options_map_fd:write(s .. '\n') end +enum_w('// IWYU pragma: private, include "nvim/option_defs.h"') +enum_w('') + --- @param s string --- @return string local lowercase_to_titlecase = function(s) @@ -24,6 +28,55 @@ end --- @type vim.option_meta[] local options = require('options').options + +-- Generate BV_ enum constants. +enum_w('/// "indir" values for buffer-local options.') +enum_w('/// These need to be defined globally, so that the BV_COUNT can be used with') +enum_w('/// b_p_script_stx[].') +enum_w('enum {') + +local bv_val = 0 + +for _, o in ipairs(options) do + assert(#o.scope == 1 or #o.scope == 2) + assert(#o.scope == 1 or o.scope[1] == 'global') + local min_scope = o.scope[#o.scope] + if min_scope == 'buffer' then + local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name)) + local bv_name = 'BV_' .. varname:sub(3):upper() + enum_w((' %s = %u,'):format(bv_name, bv_val)) + bv_val = bv_val + 1 + end +end + +enum_w((' BV_COUNT = %u, ///< must be the last one'):format(bv_val)) +enum_w('};') +enum_w('') + +-- Generate WV_ enum constants. +enum_w('/// "indir" values for window-local options.') +enum_w('/// These need to be defined globally, so that the WV_COUNT can be used in the') +enum_w('/// window structure.') +enum_w('enum {') + +local wv_val = 0 + +for _, o in ipairs(options) do + assert(#o.scope == 1 or #o.scope == 2) + assert(#o.scope == 1 or o.scope[1] == 'global') + local min_scope = o.scope[#o.scope] + if min_scope == 'window' then + local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name)) + local wv_name = 'WV_' .. varname:sub(3):upper() + enum_w((' %s = %u,'):format(wv_name, wv_val)) + wv_val = wv_val + 1 + end +end + +enum_w((' WV_COUNT = %u, ///< must be the last one'):format(wv_val)) +enum_w('};') +enum_w('') + --- @type { [string]: string } local option_index = {} diff --git a/src/nvim/globals.h b/src/nvim/globals.h index e153b03bc1..3097853bea 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -11,10 +11,9 @@ #include "nvim/getchar_defs.h" #include "nvim/iconv_defs.h" #include "nvim/macros_defs.h" -#include "nvim/mbyte.h" #include "nvim/menu_defs.h" #include "nvim/os/os_defs.h" -#include "nvim/runtime.h" +#include "nvim/runtime_defs.h" #include "nvim/state_defs.h" #include "nvim/syntax_defs.h" #include "nvim/types_defs.h" diff --git a/src/nvim/input.h b/src/nvim/input.h index 3d948fa4ca..8741dafba4 100644 --- a/src/nvim/input.h +++ b/src/nvim/input.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/event/multiqueue.h" // IWYU pragma: keep +#include "nvim/event/defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "input.h.generated.h" diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index 0b4623cbd3..16fa5f8bc0 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -9,6 +9,7 @@ #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/func_attr.h" #include "nvim/macros_defs.h" +#include "nvim/map_defs.h" #include "nvim/types_defs.h" #include "nvim/usercmd.h" // IWYU pragma: keep diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index cbdec2e0db..c3ab034c4c 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -779,156 +779,6 @@ EXTERN int p_wb; ///< 'writebackup' EXTERN OptInt p_wd; ///< 'writedelay' EXTERN int p_cdh; ///< 'cdhome' -/// "indir" values for buffer-local options. -/// These need to be defined globally, so that the BV_COUNT can be used with -/// b_p_script_stx[]. -enum { - BV_AI = 0, - BV_AR, - BV_BH, - BV_BKC, - BV_BT, - BV_EFM, - BV_GP, - BV_MP, - BV_BIN, - BV_BL, - BV_BOMB, - BV_CHANNEL, - BV_CI, - BV_CIN, - BV_CINK, - BV_CINO, - BV_CINW, - BV_CINSD, - BV_CM, - BV_CMS, - BV_COM, - BV_CPT, - BV_DICT, - BV_TSR, - BV_CSL, - BV_CFU, - BV_DEF, - BV_INC, - BV_EOF, - BV_EOL, - BV_FIXEOL, - BV_EP, - BV_ET, - BV_FENC, - BV_FP, - BV_BEXPR, - BV_FEX, - BV_FF, - BV_FLP, - BV_FO, - BV_FT, - BV_IMI, - BV_IMS, - BV_INDE, - BV_INDK, - BV_INEX, - BV_INF, - BV_ISK, - BV_KMAP, - BV_KP, - BV_LISP, - BV_LOP, - BV_LW, - BV_MENC, - BV_MA, - BV_ML, - BV_MOD, - BV_MPS, - BV_NF, - BV_OFU, - BV_PATH, - BV_PI, - BV_QE, - BV_RO, - BV_SCBK, - BV_SI, - BV_SMC, - BV_SYN, - BV_SPC, - BV_SPF, - BV_SPL, - BV_SPO, - BV_STS, - BV_SUA, - BV_SW, - BV_SWF, - BV_TFU, - BV_TSRFU, - BV_TAGS, - BV_TC, - BV_TS, - BV_TW, - BV_TX, - BV_UDF, - BV_UL, - BV_WM, - BV_VSTS, - BV_VTS, - BV_COUNT, // must be the last one -}; - -/// "indir" values for window-local options. -/// These need to be defined globally, so that the WV_COUNT can be used in the -/// window structure. -enum { - WV_LIST = 0, - WV_ARAB, - WV_COCU, - WV_COLE, - WV_CRBIND, - WV_BRI, - WV_BRIOPT, - WV_DIFF, - WV_FDC, - WV_FEN, - WV_FDI, - WV_FDL, - WV_FDM, - WV_FML, - WV_FDN, - WV_FDE, - WV_FDT, - WV_FMR, - WV_LBR, - WV_NU, - WV_RNU, - WV_VE, - WV_NUW, - WV_PVW, - WV_RL, - WV_RLC, - WV_SCBIND, - WV_SCROLL, - WV_SMS, - WV_SISO, - WV_SO, - WV_SPELL, - WV_CUC, - WV_CUL, - WV_CULOPT, - WV_CC, - WV_SBR, - WV_STC, - WV_STL, - WV_WFH, - WV_WFW, - WV_WRAP, - WV_SCL, - WV_WINHL, - WV_LCS, - WV_FCS, - WV_WINBL, - WV_WBR, - WV_COUNT, // must be the last one -}; - // Value for b_p_ul indicating the global value must be used. #define NO_LOCAL_UNDOLEVEL (-123456) diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h index 94287ea4e1..ff33b9ead1 100644 --- a/src/nvim/viml/parser/expressions.h +++ b/src/nvim/viml/parser/expressions.h @@ -8,8 +8,6 @@ #include "nvim/types_defs.h" #include "nvim/viml/parser/parser.h" -struct expr_ast_node; - // Defines whether to ignore case: // == kCCStrategyUseOption // ==# kCCStrategyMatchCase -- cgit From ba0fa4fa197330687b06c74a50b2ccd4800f5881 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 22 Dec 2023 13:32:46 +0800 Subject: refactor(IWYU): add "private" pragma to more generated headers (#26706) "export" only prevents IWYU from adding these headers if the headers that export them are included, while "private" ensures that IWYU never adds these headers. --- src/nvim/api/private/dispatch.h | 4 ++-- src/nvim/api/ui.h | 2 +- src/nvim/generators/gen_api_dispatch.lua | 14 ++++++++------ src/nvim/generators/gen_declarations.lua | 16 ++++++++++++++++ src/nvim/option.c | 1 - src/nvim/option_defs.h | 2 +- src/nvim/ui.h | 2 +- src/nvim/ui_client.h | 2 +- 8 files changed, 30 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h index d322c1ceca..9b167a7b9e 100644 --- a/src/nvim/api/private/dispatch.h +++ b/src/nvim/api/private/dispatch.h @@ -26,6 +26,6 @@ extern const MsgpackRpcRequestHandler method_handlers[]; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/dispatch.h.generated.h" -# include "api/private/dispatch_wrappers.h.generated.h" // IWYU pragma: export -# include "keysets_defs.generated.h" // IWYU pragma: export +# include "api/private/dispatch_wrappers.h.generated.h" +# include "keysets_defs.generated.h" #endif diff --git a/src/nvim/api/ui.h b/src/nvim/api/ui.h index b1f4ff97d9..9147f1d870 100644 --- a/src/nvim/api/ui.h +++ b/src/nvim/api/ui.h @@ -9,5 +9,5 @@ #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/ui.h.generated.h" -# include "ui_events_remote.h.generated.h" // IWYU pragma: export +# include "ui_events_remote.h.generated.h" #endif diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 5928999967..791edfff96 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -106,7 +106,7 @@ for i = 6, #arg do end headers[#headers + 1] = parts[#parts - 1] .. '/' .. parts[#parts] - local input = io.open(full_path, 'rb') + local input = assert(io.open(full_path, 'rb')) local tmp = c_grammar.grammar:match(input:read('*all')) for j = 1, #tmp do @@ -216,16 +216,16 @@ end -- serialize the API metadata using msgpack and embed into the resulting -- binary for easy querying by clients -local funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb') +local funcs_metadata_output = assert(io.open(funcs_metadata_outputf, 'wb')) local packed = mpack.encode(exported_functions) local dump_bin_array = require('generators.dump_bin_array') dump_bin_array(funcs_metadata_output, 'funcs_metadata', packed) funcs_metadata_output:close() -- start building the dispatch wrapper output -local output = io.open(dispatch_outputf, 'wb') +local output = assert(io.open(dispatch_outputf, 'wb')) -local keysets_defs = io.open(keysets_outputf, 'wb') +local keysets_defs = assert(io.open(keysets_outputf, 'wb')) -- =========================================================================== -- NEW API FILES MUST GO HERE. @@ -257,6 +257,8 @@ output:write([[ ]]) +keysets_defs:write('// IWYU pragma: private, include "nvim/api/private/dispatch.h"\n\n') + for _, k in ipairs(keysets) do local c_name = {} @@ -633,7 +635,7 @@ output:write(hashfun) output:close() functions.keysets = keysets -local mpack_output = io.open(mpack_outputf, 'wb') +local mpack_output = assert(io.open(mpack_outputf, 'wb')) mpack_output:write(mpack.encode(functions)) mpack_output:close() @@ -653,7 +655,7 @@ local function write_shifted_output(_, str) end -- start building lua output -output = io.open(lua_c_bindings_outputf, 'wb') +output = assert(io.open(lua_c_bindings_outputf, 'wb')) output:write([[ #include diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua index 9fd2750f52..5d1e586fe6 100644 --- a/src/nvim/generators/gen_declarations.lua +++ b/src/nvim/generators/gen_declarations.lua @@ -207,6 +207,22 @@ if fname:find('.*/src/nvim/.*%.c$') then // IWYU pragma: private, include "%s" ]]):format(header_fname:gsub('.*/src/nvim/', 'nvim/')) .. non_static end +elseif non_static_fname:find('/include/api/private/dispatch_wrappers%.h%.generated%.h$') then + non_static = [[ +// IWYU pragma: private, include "nvim/api/private/dispatch.h" +]] .. non_static +elseif non_static_fname:find('/include/ui_events_call%.h%.generated%.h$') then + non_static = [[ +// IWYU pragma: private, include "nvim/ui.h" +]] .. non_static +elseif non_static_fname:find('/include/ui_events_client%.h%.generated%.h$') then + non_static = [[ +// IWYU pragma: private, include "nvim/ui_client.h" +]] .. non_static +elseif non_static_fname:find('/include/ui_events_remote%.h%.generated%.h$') then + non_static = [[ +// IWYU pragma: private, include "nvim/api/ui.h" +]] .. non_static end local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"' diff --git a/src/nvim/option.c b/src/nvim/option.c index 49a8c468d6..4969ac7f1d 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2,7 +2,6 @@ // - Put it in options.lua // - For a global option: Add a variable for it in option_vars.h. // - For a buffer or window local option: -// - Add a BV_XX or WV_XX entry to option_vars.h // - Add a variable to the window or buffer struct in buffer_defs.h. // - For a window option, add some code to copy_winopt(). // - For a window string option, add code to check_winopt() diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 62c02989a2..72fb5a92fc 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -131,5 +131,5 @@ typedef enum { } OptReqScope; #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "options_enum.generated.h" // IWYU pragma: export +# include "options_enum.generated.h" #endif diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 8b00e4e917..b783e4b6d3 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -27,7 +27,7 @@ EXTERN const char *ui_ext_names[] INIT( = { // uncrustify:off #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui.h.generated.h" -# include "ui_events_call.h.generated.h" // IWYU pragma: export +# include "ui_events_call.h.generated.h" #endif // uncrustify:on diff --git a/src/nvim/ui_client.h b/src/nvim/ui_client.h index 93170ed86d..8603ae9ca1 100644 --- a/src/nvim/ui_client.h +++ b/src/nvim/ui_client.h @@ -39,6 +39,6 @@ EXTERN bool ui_client_forward_stdin INIT( = false); // uncrustify:off #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_client.h.generated.h" -# include "ui_events_client.h.generated.h" // IWYU pragma: export +# include "ui_events_client.h.generated.h" #endif // uncrustify:on -- cgit From 66ac327db27c8097cfa6c1f136dca96151b074f4 Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 22 Nov 2023 19:58:17 +0100 Subject: refactor(drawline): remove LineDrawState and wlv->saved_n_extra We do not need an enum to keep track of what place in win_line() we currently are at. We already have a variable which keeps track where in the code we currently are (and thus what part of the line we are currently rendering), it is called the _program counter_. When we need non-linear or self-referential control-flow anyway for a laugh, we have a mechanism for that, it is called _function calls_. Do not "save" and "restore" the wlv->n_extra state every time the columns are to be drawn. This sort of thing needs to go away. Instead of setting the n_extra variables and then going to the outer while loop, the text in the columns can be rendered by just simply putting the text into the cells of the screen line, right away. Even in nvim this can be tricky sometimes, luckily we can use function calls to abstract this logic, which means that this handy data structure called the _call stack_ is handling saving away state temporarily, and restoring it back when we need it again. Lastly, but not least, as we now have direct control how signs are rendered, these can be stored as schar_T[2] and be directly put on screen as such. --- src/nvim/api/extmark.c | 7 +- src/nvim/decoration.c | 36 +-- src/nvim/decoration_defs.h | 8 +- src/nvim/drawline.c | 697 +++++++++++++++++++-------------------------- src/nvim/sign.c | 68 +++-- src/nvim/sign_defs.h | 7 +- src/nvim/statusline.c | 22 +- src/nvim/types_defs.h | 2 + 8 files changed, 388 insertions(+), 459 deletions(-) (limited to 'src') diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index ec47d7227e..fa3c5afcc6 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -665,9 +665,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer } if (HAS_KEY(opts, set_extmark, sign_text)) { - sign.text.ptr = NULL; - VALIDATE_S(init_sign_text(NULL, &sign.text.ptr, opts->sign_text.data), - "sign_text", "", { + sign.text[0] = 0; + VALIDATE_S(init_sign_text(NULL, sign.text, opts->sign_text.data), "sign_text", "", { goto error; }); sign.flags |= kSHIsSign; @@ -785,7 +784,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer uint32_t decor_indexed = DECOR_ID_INVALID; if (sign.flags & kSHIsSign) { decor_indexed = decor_put_sh(sign); - if (sign.text.ptr != NULL) { + if (sign.text[0]) { decor_flags |= MT_FLAG_DECOR_SIGNTEXT; } if (sign.number_hl_id || sign.line_hl_id || sign.cursorline_hl_id) { diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 7b3a32167e..bddc48b8c7 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -6,6 +6,7 @@ #include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/ascii_defs.h" #include "nvim/buffer_defs.h" #include "nvim/decoration.h" #include "nvim/drawscreen.h" @@ -20,6 +21,7 @@ #include "nvim/move.h" #include "nvim/option_vars.h" #include "nvim/pos_defs.h" +#include "nvim/sign.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "decoration.c.generated.h" @@ -159,7 +161,7 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item) DecorSignHighlight conv = { .flags = item.flags, .priority = item.priority, - .text.sc[0] = item.conceal_char, + .text[0] = item.conceal_char, .hl_id = item.hl_id, .number_hl_id = 0, .line_hl_id = 0, @@ -208,7 +210,7 @@ void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2) if (sh->flags & kSHIsSign) { sh->sign_add_id = sign_add_id++; buf->b_signs++; - if (sh->text.ptr) { + if (sh->text[0]) { buf->b_signs_with_text++; buf_signcols_invalidate_range(buf, row1, row2, 1); } @@ -254,7 +256,7 @@ void buf_remove_decor_sh(buf_T *buf, int row1, int row2, DecorSignHighlight *sh) if (sh->flags & kSHIsSign) { assert(buf->b_signs > 0); buf->b_signs--; - if (sh->text.ptr) { + if (sh->text[0]) { assert(buf->b_signs_with_text > 0); buf->b_signs_with_text--; if (row2 >= row1) { @@ -312,9 +314,6 @@ void decor_free_inner(DecorVirtText *vt, uint32_t first_idx) uint32_t idx = first_idx; while (idx != DECOR_ID_INVALID) { DecorSignHighlight *sh = &kv_A(decor_items, idx); - if (sh->flags & kSHIsSign) { - xfree(sh->text.ptr); - } if (sh->flags & kSHIsSign) { xfree(sh->sign_name); } @@ -363,8 +362,11 @@ void decor_check_invalid_glyphs(void) { for (size_t i = 0; i < kv_size(decor_items); i++) { DecorSignHighlight *it = &kv_A(decor_items, i); - if ((it->flags & kSHConceal) && schar_high(it->text.sc[0])) { - it->text.sc[0] = schar_from_char(schar_get_first_codepoint(it->text.sc[0])); + int width = (it->flags & kSHIsSign) ? SIGN_WIDTH : ((it->flags & kSHConceal) ? 1 : 0); + for (int j = 0; j < width; j++) { + if (schar_high(it->text[j])) { + it->text[j] = schar_from_char(schar_get_first_codepoint(it->text[j])); + } } } } @@ -662,7 +664,7 @@ next_mark: if (item.start_row == state->row && item.start_col == col) { DecorSignHighlight *sh = &item.data.sh; conceal = 2; - conceal_char = sh->text.sc[0]; + conceal_char = sh->text[0]; state->col_until = MIN(state->col_until, item.start_col); conceal_attr = item.attr_id; } @@ -730,7 +732,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[], while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) { if (!mt_invalid(pair.start) && mt_decor_sign(pair.start)) { DecorSignHighlight *sh = decor_find_sign(mt_decor(pair.start)); - num_text += (sh->text.ptr != NULL); + num_text += (sh->text[0] != NUL); kv_push(signs, ((SignItem){ sh, pair.start.id })); } } @@ -742,7 +744,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[], } if (!mt_end(mark) && !mt_invalid(mark) && mt_decor_sign(mark)) { DecorSignHighlight *sh = decor_find_sign(mt_decor(mark)); - num_text += (sh->text.ptr != NULL); + num_text += (sh->text[0] != NUL); kv_push(signs, ((SignItem){ sh, mark.id })); } @@ -756,8 +758,8 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[], for (size_t i = 0; i < kv_size(signs); i++) { DecorSignHighlight *sh = kv_A(signs, i).sh; - if (idx >= 0 && sh->text.ptr) { - sattrs[idx].text = sh->text.ptr; + if (idx >= 0 && sh->text[0]) { + memcpy(sattrs[idx].text, sh->text, SIGN_WIDTH * sizeof(sattr_T)); sattrs[idx--].hl_id = sh->hl_id; } if (*num_id == 0) { @@ -1034,7 +1036,7 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name) PUT(*dict, "hl_eol", BOOLEAN_OBJ(sh_hl.flags & kSHHlEol)); if (sh_hl.flags & kSHConceal) { char buf[MAX_SCHAR_SIZE]; - schar_get(buf, sh_hl.text.sc[0]); + schar_get(buf, sh_hl.text[0]); PUT(*dict, "conceal", CSTR_TO_OBJ(buf)); } @@ -1082,8 +1084,10 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name) } if (sh_sign.flags & kSHIsSign) { - if (sh_sign.text.ptr) { - PUT(*dict, "sign_text", CSTR_TO_OBJ(sh_sign.text.ptr)); + if (sh_sign.text[0]) { + char buf[SIGN_WIDTH * MAX_SCHAR_SIZE]; + describe_sign_text(buf, sh_sign.text); + PUT(*dict, "sign_text", CSTR_TO_OBJ(buf)); } if (sh_sign.sign_name) { diff --git a/src/nvim/decoration_defs.h b/src/nvim/decoration_defs.h index f272753f46..4550ae0a42 100644 --- a/src/nvim/decoration_defs.h +++ b/src/nvim/decoration_defs.h @@ -59,11 +59,7 @@ typedef struct { uint16_t flags; DecorPriority priority; int hl_id; // if sign: highlight of sign text - // TODO(bfredl): Later signs should use sc[2] as well. - union { - char *ptr; // sign - schar_T sc[2]; // conceal text (only sc[0] used) - } text; + schar_T text[SIGN_WIDTH]; // conceal text only uses text[0] // NOTE: if more functionality is added to a Highlight these should be overloaded // or restructured char *sign_name; @@ -74,7 +70,7 @@ typedef struct { uint32_t next; } DecorSignHighlight; -#define DECOR_SIGN_HIGHLIGHT_INIT { 0, DECOR_PRIORITY_BASE, 0, { .ptr = NULL }, NULL, 0, 0, 0, 0, \ +#define DECOR_SIGN_HIGHLIGHT_INIT { 0, DECOR_PRIORITY_BASE, 0, { 0, 0 }, NULL, 0, 0, 0, 0, \ DECOR_ID_INVALID } enum { diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 4f62fda2c5..29221e64f9 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -52,23 +52,8 @@ #define MB_FILLER_CHAR '<' // character used when a double-width character doesn't fit. -/// possible draw states in win_line(), drawn in sequence. -typedef enum { - WL_START = 0, // nothing done yet - WL_CMDLINE, // cmdline window column - WL_FOLD, // 'foldcolumn' - WL_SIGN, // column for signs - WL_NR, // line number - WL_STC, // 'statuscolumn' - WL_BRI, // 'breakindent' - WL_SBR, // 'showbreak' or 'diff' - WL_LINE, // text in the line -} LineDrawState; - /// structure with variables passed between win_line() and other functions typedef struct { - LineDrawState draw_state; ///< what to draw next - linenr_T lnum; ///< line number to be drawn foldinfo_T foldinfo; ///< fold info for this line @@ -102,18 +87,8 @@ typedef struct { int c_extra; ///< extra chars, all the same int c_final; ///< final char, mandatory if set - int n_closing; ///< number of chars in fdc which will be closing - bool extra_for_extmark; ///< n_extra set for inline virtual text - // saved "extra" items for when draw_state becomes WL_LINE (again) - int saved_n_extra; - char *saved_p_extra; - bool saved_extra_for_extmark; - int saved_c_extra; - int saved_c_final; - int saved_char_attr; - char extra[57]; ///< sign, line number and 'fdc' must fit in here hlf_T diff_hlf; ///< type of diff highlighting @@ -136,6 +111,8 @@ typedef struct { ///< or w_skipcol or concealing int skipped_cells; ///< nr of skipped cells for virtual text ///< to be added to wlv.vcol later + + int *color_cols; ///< if not NULL, highlight colorcolumn using according columns array } winlinevars_T; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -163,15 +140,17 @@ void drawline_free_all_mem(void) } #endif -/// Advance **color_cols -/// -/// @return true when there are columns to draw. -static bool advance_color_col(int vcol, int **color_cols) +/// Advance wlv->color_cols if not NULL +static void advance_color_col(winlinevars_T *wlv, int vcol) { - while (**color_cols >= 0 && vcol > **color_cols) { - (*color_cols)++; + if (wlv->color_cols) { + while (*wlv->color_cols >= 0 && vcol > *wlv->color_cols) { + wlv->color_cols++; + } + if (*wlv->color_cols < 0) { + wlv->color_cols = NULL; + } } - return **color_cols >= 0; } /// Used when 'cursorlineopt' contains "screenline": compute the margins between @@ -360,6 +339,38 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, return col; } +// TODO(bfredl): integrate with grid.c linebuf code? madness? +static void draw_col_buf(win_T *wp, winlinevars_T *wlv, const char *text, size_t len, int attr, + bool vcol) +{ + const char *ptr = text; + while (ptr < text + len && wlv->off < wp->w_grid.cols) { + int cells = line_putchar(wp->w_buffer, &ptr, &linebuf_char[wlv->off], + wp->w_grid.cols - wlv->off, wlv->off); + int myattr = attr; + if (vcol) { + advance_color_col(wlv, wlv->vcol); + if (wlv->color_cols && wlv->vcol == *wlv->color_cols) { + myattr = hl_combine_attr(win_hl_attr(wp, HLF_MC), myattr); + } + } + for (int c = 0; c < cells; c++) { + linebuf_attr[wlv->off] = myattr; + linebuf_vcol[wlv->off] = vcol ? wlv->vcol++ : -1; + wlv->off++; + } + } +} + +static void draw_col_fill(winlinevars_T *wlv, schar_T fillchar, int width, int attr) +{ + for (int i = 0; i < width; i++) { + linebuf_char[wlv->off] = fillchar; + linebuf_attr[wlv->off] = attr; + wlv->off++; + } +} + /// Return true if CursorLineSign highlight is to be used. static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum) { @@ -368,28 +379,18 @@ static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum) && (wp->w_p_culopt_flags & CULOPT_NBR); } -static char fdc_buf[MB_MAXCHAR * 10 + 1]; - /// Setup for drawing the 'foldcolumn', if there is one. -static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv) +static void draw_foldcolumn(win_T *wp, winlinevars_T *wlv) { int fdc = compute_foldcolumn(wp, 0); if (fdc <= 0) { return; } - // Use a separate buffer as `extra_buf` might be in use. - wlv->n_extra = (int)fill_foldcolumn(fdc_buf, wp, wlv->foldinfo, wlv->lnum, - &wlv->n_closing); - fdc_buf[wlv->n_extra] = NUL; - wlv->p_extra = fdc_buf; - wlv->c_extra = NUL; - wlv->c_final = NUL; - if (use_cursor_line_highlight(wp, wlv->lnum)) { - wlv->char_attr = win_hl_attr(wp, HLF_CLF); - } else { - wlv->char_attr = win_hl_attr(wp, HLF_FC); - } + int attr = use_cursor_line_highlight(wp, wlv->lnum) + ? win_hl_attr(wp, HLF_CLF) : win_hl_attr(wp, HLF_FC); + + fill_foldcolumn(wlv, wp, wlv->foldinfo, wlv->lnum, attr, NULL); } /// Fills the foldcolumn at "p" for window "wp". @@ -401,29 +402,25 @@ static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv) /// /// Assume monocell characters /// @return number of chars added to \param p -size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int *n_closing) +size_t fill_foldcolumn(void *maybe_wlv, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, + schar_T *out_buffer) { int i = 0; int fdc = compute_foldcolumn(wp, 0); // available cell width - size_t char_counter = 0; - int symbol = 0; - int len = 0; + int char_counter = 0; bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0; - // Init to all spaces. - memset(p, ' ', MB_MAXCHAR * (size_t)fdc + 1); int level = foldinfo.fi_level; + winlinevars_T *wlv = maybe_wlv; // TODO(bfredl): this is bullshit + // If the column is too narrow, we start at the lowest level that // fits and use numbers to indicate the depth. - int first_level = level - fdc - closed + 1; - if (first_level < 1) { - first_level = 1; - } + int first_level = MAX(level - fdc - closed + 1, 1); for (i = 0; i < MIN(fdc, level); i++) { - if (foldinfo.fi_lnum == lnum - && first_level + i >= foldinfo.fi_low_level) { + int symbol = 0; + if (foldinfo.fi_lnum == lnum && first_level + i >= foldinfo.fi_low_level) { symbol = wp->w_p_fcs_chars.foldopen; } else if (first_level == 1) { symbol = wp->w_p_fcs_chars.foldsep; @@ -433,64 +430,74 @@ size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, i symbol = '>'; } - len = utf_char2bytes(symbol, &p[char_counter]); - char_counter += (size_t)len; + if (out_buffer) { + out_buffer[char_counter++] = schar_from_char(symbol); + } else { + linebuf_vcol[wlv->off] = -3; + linebuf_attr[wlv->off] = attr; + linebuf_char[wlv->off++] = schar_from_char(symbol); + char_counter++; + } + if (first_level + i >= level) { i++; break; } } - int n_closing_val = i; - if (closed) { - if (symbol != 0) { + if (char_counter > 0) { // rollback previous write - char_counter -= (size_t)len; - memset(&p[char_counter], ' ', (size_t)len); - n_closing_val--; + char_counter--; + if (!out_buffer) { + wlv->off--; + } + } + if (out_buffer) { + out_buffer[char_counter++] = schar_from_char(wp->w_p_fcs_chars.foldclosed); + } else { + linebuf_vcol[wlv->off] = -2; + linebuf_attr[wlv->off] = attr; + linebuf_char[wlv->off++] = schar_from_char(wp->w_p_fcs_chars.foldclosed); + char_counter++; } - len = utf_char2bytes(wp->w_p_fcs_chars.foldclosed, &p[char_counter]); - char_counter += (size_t)len; } - if (n_closing) { - *n_closing = n_closing_val; + int width = MAX(char_counter + (fdc - i), fdc); + if (char_counter < width) { + if (out_buffer) { + while (char_counter < width) { + out_buffer[char_counter++] = schar_from_ascii(' '); + } + } else { + draw_col_fill(wlv, schar_from_ascii(' '), width - char_counter, attr); + } } - - return MAX(char_counter + (size_t)(fdc - i), (size_t)fdc); + return (size_t)width; } /// Get information needed to display the sign in line "wlv->lnum" in window "wp". /// If "nrcol" is true, the sign is going to be displayed in the number column. /// Otherwise the sign is going to be displayed in the sign column. If there is no /// sign, draw blank cells instead. -static void get_sign_display_info(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, - int sign_cul_attr) +static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, int sign_cul_attr) { SignTextAttrs sattr = wlv->sattrs[sign_idx]; wlv->c_final = NUL; - if (sattr.text && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) { - size_t fill = nrcol ? (size_t)number_width(wp) - SIGN_WIDTH : 0; - size_t sign_len = strlen(sattr.text); - - // Spaces + sign: " " + ">>" + ' ' - wlv->n_extra = (int)(fill + sign_len + nrcol); - if (nrcol) { - memset(wlv->extra, ' ', (size_t)wlv->n_extra); - } - memcpy(wlv->extra + fill, sattr.text, sign_len); - wlv->p_extra = wlv->extra; - wlv->c_extra = NUL; - wlv->char_attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr) - ? sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0; + if (sattr.text[0] && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) { + int attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr) + ? sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0; + int fill = nrcol ? number_width(wp) + 1 : SIGN_WIDTH; + draw_col_fill(wlv, schar_from_ascii(' '), fill, attr); + int sign_pos = wlv->off - SIGN_WIDTH - (int)nrcol; + linebuf_char[sign_pos] = sattr.text[0]; + linebuf_char[sign_pos + 1] = sattr.text[1]; } else { + assert(!nrcol); // handled in draw_lnum_col() wlv->c_extra = ' '; - wlv->n_extra = nrcol ? number_width(wp) + 1 : SIGN_WIDTH; - if (!nrcol) { - wlv->char_attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC); - } + int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC); + draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, attr); } } @@ -557,7 +564,7 @@ static int get_line_number_attr(win_T *wp, winlinevars_T *wlv) /// Display the absolute or relative line number. After the first row fill with /// blanks when the 'n' flag isn't in 'cpo'. -static void handle_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int sign_cul_attr) +static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int sign_cul_attr) { bool has_cpo_n = vim_strchr(p_cpo, CPO_NUMCOL) != NULL; @@ -568,33 +575,30 @@ static void handle_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, in && !((has_cpo_n && !wp->w_p_bri) && wp->w_skipcol > 0 && wlv->lnum == wp->w_topline)) { // If 'signcolumn' is set to 'number' and a sign is present in "lnum", // then display the sign instead of the line number. - if (wp->w_minscwidth == SCL_NUM && wlv->sattrs[0].text) { - get_sign_display_info(true, wp, wlv, 0, sign_cul_attr); + if (wp->w_minscwidth == SCL_NUM && wlv->sattrs[0].text[0] + && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) { + draw_sign(true, wp, wlv, 0, sign_cul_attr); } else { // Draw the line number (empty space after wrapping). + int width = number_width(wp) + 1; + int attr = (sign_num_attr > 0 && wlv->filler_todo <= 0) + ? sign_num_attr : get_line_number_attr(wp, wlv); if (wlv->row == wlv->startrow + wlv->filler_lines && (wp->w_skipcol == 0 || wlv->row > 0 || (wp->w_p_nu && wp->w_p_rnu))) { - get_line_number_str(wp, wlv->lnum, wlv->extra, sizeof(wlv->extra)); + char buf[32]; + get_line_number_str(wp, wlv->lnum, buf, sizeof(buf)); if (wp->w_skipcol > 0 && wlv->startrow == 0) { - for (wlv->p_extra = wlv->extra; *wlv->p_extra == ' '; wlv->p_extra++) { - *wlv->p_extra = '-'; + for (char *c = buf; *c == ' '; c++) { + *c = '-'; } } if (wp->w_p_rl) { // reverse line numbers - char *num = skipwhite(wlv->extra); + char *num = skipwhite(buf); rl_mirror_ascii(num, skiptowhite(num)); } - wlv->p_extra = wlv->extra; - wlv->c_extra = NUL; + draw_col_buf(wp, wlv, buf, (size_t)width, attr, false); } else { - wlv->c_extra = ' '; - } - wlv->c_final = NUL; - wlv->n_extra = number_width(wp) + 1; - if (sign_num_attr > 0) { - wlv->char_attr = sign_num_attr; - } else { - wlv->char_attr = get_line_number_attr(wp, wlv); + draw_col_fill(wlv, schar_from_ascii(' '), width, attr); } } } @@ -663,124 +667,108 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T /// /// @param stcp Status column attributes /// @param[in,out] wlv -static void get_statuscol_display_info(statuscol_T *stcp, winlinevars_T *wlv) +static void draw_statuscol(win_T *wp, statuscol_T *stcp, winlinevars_T *wlv) { - wlv->c_extra = NUL; - wlv->c_final = NUL; do { - wlv->draw_state = WL_STC; - wlv->char_attr = stcp->cur_attr; - wlv->p_extra = stcp->textp; - char *const section_end = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end; - wlv->n_extra = (int)(section_end - stcp->textp); + int attr = stcp->cur_attr; + char *text = stcp->textp; + char *section_end = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end; + ptrdiff_t len = section_end - text; // Prepare for next highlight section if not yet at the end if (section_end < stcp->text_end) { int hl = stcp->hlrecp->userhl; stcp->textp = stcp->hlrecp->start; stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr; stcp->hlrecp++; - wlv->draw_state = WL_STC - 1; + } else { + stcp->textp = section_end; } // Skip over empty highlight sections - } while (wlv->n_extra == 0 && stcp->textp < stcp->text_end); - if (wlv->n_extra > 0) { - static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * 2) * MB_MAXBYTES + 1]; - wlv->n_extra = (int)transstr_buf(wlv->p_extra, wlv->n_extra, transbuf, sizeof transbuf, true); - wlv->p_extra = transbuf; - } + if (len) { + static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * SIGN_WIDTH) * MB_MAXBYTES + 1]; + size_t translen = transstr_buf(text, len, transbuf, sizeof transbuf, true); + draw_col_buf(wp, wlv, transbuf, translen, attr, false); + } + } while (stcp->textp < stcp->text_end); } static void handle_breakindent(win_T *wp, winlinevars_T *wlv) { - if (wp->w_briopt_sbr && wlv->draw_state == WL_BRI - 1 - && *get_showbreak_value(wp) != NUL) { - // draw indent after showbreak value - wlv->draw_state = WL_BRI; - } else if (wp->w_briopt_sbr && wlv->draw_state == WL_SBR) { - // after the showbreak, draw the breakindent - wlv->draw_state = WL_BRI - 1; - } - // draw 'breakindent': indent wrapped text accordingly - if (wlv->draw_state == WL_BRI - 1 && wlv->n_extra == 0) { - wlv->draw_state = WL_BRI; - // if wlv->need_showbreak is set, breakindent also applies - if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines - || wlv->need_showbreak)) { - wlv->char_attr = 0; - if (wlv->diff_hlf != (hlf_T)0) { - wlv->char_attr = win_hl_attr(wp, (int)wlv->diff_hlf); - } - wlv->p_extra = NULL; - wlv->c_extra = ' '; - wlv->c_final = NUL; - wlv->n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, wlv->lnum)); - if (wlv->row == wlv->startrow) { - wlv->n_extra -= win_col_off2(wp); - if (wlv->n_extra < 0) { - wlv->n_extra = 0; - } - } - if (wp->w_skipcol > 0 && wlv->startrow == 0 && wp->w_p_wrap && wp->w_briopt_sbr) { - wlv->need_showbreak = false; + // if wlv->need_showbreak is set, breakindent also applies + if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines + || wlv->need_showbreak)) { + int attr = 0; + if (wlv->diff_hlf != (hlf_T)0) { + attr = win_hl_attr(wp, (int)wlv->diff_hlf); + } + int num = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, wlv->lnum)); + if (wlv->row == wlv->startrow) { + num -= win_col_off2(wp); + if (wlv->n_extra < 0) { + num = 0; } - // Correct end of highlighted area for 'breakindent', - // required wen 'linebreak' is also set. - if (wlv->tocol == wlv->vcol) { - wlv->tocol += wlv->n_extra; + } + + // Correct end of highlighted area for 'breakindent', + // required wen 'linebreak' is also set. + if (wlv->tocol == wlv->vcol) { + wlv->tocol += num; + } + + for (int i = 0; i < num; i++) { + linebuf_char[wlv->off] = schar_from_ascii(' '); + + advance_color_col(wlv, wlv->vcol); + int myattr = attr; + if (wlv->color_cols && wlv->vcol == *wlv->color_cols) { + myattr = hl_combine_attr(win_hl_attr(wp, HLF_MC), myattr); } + linebuf_attr[wlv->off] = myattr; + linebuf_vcol[wlv->off] = wlv->vcol++; // These are vcols, sorry I don't make the rules + wlv->off++; + } + + if (wp->w_skipcol > 0 && wlv->startrow == 0 && wp->w_p_wrap && wp->w_briopt_sbr) { + wlv->need_showbreak = false; } } } static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv) { + int remaining = wp->w_grid.cols - wlv->off; if (wlv->filler_todo > wlv->filler_lines - wlv->n_virt_lines) { // TODO(bfredl): check this doesn't inhibit TUI-style // clear-to-end-of-line. - wlv->c_extra = ' '; - wlv->c_final = NUL; - wlv->n_extra = wp->w_grid.cols - wlv->col; - wlv->char_attr = 0; + draw_col_fill(wlv, schar_from_ascii(' '), remaining, 0); } else if (wlv->filler_todo > 0) { // Draw "deleted" diff line(s) - if (char2cells(wp->w_p_fcs_chars.diff) > 1) { - wlv->c_extra = '-'; - wlv->c_final = NUL; - } else { - wlv->c_extra = wp->w_p_fcs_chars.diff; - wlv->c_final = NUL; - } - wlv->n_extra = wp->w_grid.cols - wlv->col; - wlv->char_attr = win_hl_attr(wp, HLF_DED); + int c = (char2cells(wp->w_p_fcs_chars.diff) > 1) ? '-' : wp->w_p_fcs_chars.diff; + draw_col_fill(wlv, schar_from_char(c), remaining, win_hl_attr(wp, HLF_DED)); } char *const sbr = get_showbreak_value(wp); if (*sbr != NUL && wlv->need_showbreak) { // Draw 'showbreak' at the start of each broken line. - wlv->p_extra = sbr; - wlv->c_extra = NUL; - wlv->c_final = NUL; - wlv->n_extra = (int)strlen(sbr); - wlv->char_attr = win_hl_attr(wp, HLF_AT); if (wp->w_skipcol == 0 || wlv->startrow != 0 || !wp->w_p_wrap) { wlv->need_showbreak = false; } - wlv->vcol_sbr = wlv->vcol + mb_charlen(sbr); + // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'. + int attr = hl_combine_attr(wlv->cul_attr, win_hl_attr(wp, HLF_AT)); + int vcol_before = wlv->vcol; + draw_col_buf(wp, wlv, sbr, strlen(sbr), attr, true); + wlv->vcol_sbr = wlv->vcol; // Correct start of highlighted area for 'showbreak'. - if (wlv->fromcol >= wlv->vcol && wlv->fromcol < wlv->vcol_sbr) { + if (wlv->fromcol >= vcol_before && wlv->fromcol < wlv->vcol_sbr) { wlv->fromcol = wlv->vcol_sbr; } // Correct end of highlighted area for 'showbreak', // required when 'linebreak' is also set. - if (wlv->tocol == wlv->vcol) { - wlv->tocol += wlv->n_extra; - } - // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'. - if (wlv->cul_attr) { - wlv->char_attr = hl_combine_attr(wlv->cul_attr, wlv->char_attr); + if (wlv->tocol == vcol_before) { + wlv->tocol = wlv->vcol; } } } @@ -943,37 +931,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra) wlv->col = 0; wlv->off = 0; wlv->need_lbr = false; - - if (save_extra) { - // reset the drawing state for the start of a wrapped line - wlv->draw_state = WL_START; - wlv->saved_n_extra = wlv->n_extra; - wlv->saved_p_extra = wlv->p_extra; - wlv->saved_extra_for_extmark = wlv->extra_for_extmark; - wlv->saved_c_extra = wlv->c_extra; - wlv->saved_c_final = wlv->c_final; - wlv->need_lbr = true; - wlv->saved_char_attr = wlv->char_attr; - - wlv->n_extra = 0; - } -} - -/// Called when wlv->draw_state is set to WL_LINE. -static void win_line_continue(winlinevars_T *wlv) -{ - if (wlv->saved_n_extra > 0) { - // Continue item from end of wrapped line. - wlv->n_extra = wlv->saved_n_extra; - wlv->saved_n_extra = 0; - wlv->c_extra = wlv->saved_c_extra; - wlv->c_final = wlv->saved_c_final; - wlv->p_extra = wlv->saved_p_extra; - wlv->extra_for_extmark = wlv->saved_extra_for_extmark; - wlv->char_attr = wlv->saved_char_attr; - } else { - wlv->char_attr = 0; - } + memset(linebuf_vcol, -1, (size_t)wp->w_grid.cols * sizeof(*linebuf_vcol)); } /// Display line "lnum" of window "wp" on the screen. @@ -1025,8 +983,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl int folded_attr = 0; // attributes for folded line int save_did_emsg; int eol_hl_off = 0; // 1 if highlighted char after EOL - bool draw_color_col = false; // highlight colorcolumn - int *color_cols = NULL; // pointer to according columns array #define SPWORDLEN 150 char nextline[SPWORDLEN * 2]; // text with start of the next line int nextlinecol = 0; // column where nextline[] starts @@ -1079,7 +1035,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl bool is_concealing = false; bool did_wcol = false; int old_boguscols = 0; -#define VCOL_HLC (wlv.vcol - wlv.vcol_off) +#define vcol_hlc(wlv) ((wlv).vcol - (wlv).vcol_off) #define FIX_FOR_BOGUSCOLS \ { \ wlv.n_extra += wlv.vcol_off; \ @@ -1136,10 +1092,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } // Check for columns to display for 'colorcolumn'. - color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols; - if (color_cols != NULL) { - draw_color_col = advance_color_col(VCOL_HLC, &color_cols); - } + wlv.color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols; + advance_color_col(&wlv, vcol_hlc(wlv)); // handle Visual active in this window if (VIsual_active && wp->w_buffer == curwin->w_buffer) { @@ -1453,7 +1407,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // - the visual mode is active, // the end of the line may be before the start of the displayed part. if (wlv.vcol < v && (wp->w_p_cuc - || draw_color_col + || wlv.color_cols || virtual_active() || (VIsual_active && wp->w_buffer == curwin->w_buffer))) { wlv.vcol = (colnr_T)v; @@ -1550,6 +1504,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } win_line_start(wp, &wlv, false); + bool draw_cols = true; + int leftcols_width = 0; // won't highlight after TERM_ATTRS_MAX columns int term_attrs[TERM_ATTRS_MAX] = { 0 }; @@ -1558,7 +1514,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl extra_check = true; } - int sign_idx = 0; int virt_line_index; int virt_line_offset = -1; // Repeat for the whole displayed line. @@ -1569,119 +1524,85 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl bool did_decrement_ptr = false; // Skip this quickly when working on the text. - if (wlv.draw_state != WL_LINE) { + if (draw_cols) { if (cul_screenline) { wlv.cul_attr = 0; wlv.line_attr = line_attr_save; wlv.line_attr_lowprio = line_attr_lowprio_save; } - if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0) { - wlv.draw_state = WL_CMDLINE; - if (cmdwin_type != 0 && wp == curwin) { - // Draw the cmdline character. - wlv.n_extra = 1; - wlv.c_extra = cmdwin_type; - wlv.c_final = NUL; - wlv.char_attr = win_hl_attr(wp, HLF_AT); - } - } - - if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) { - if (wlv.filler_todo > 0) { - int index = wlv.filler_todo - (wlv.filler_lines - wlv.n_virt_lines); - if (index > 0) { - virt_line_index = (int)kv_size(virt_lines) - index; - assert(virt_line_index >= 0); - virt_line_offset = kv_A(virt_lines, virt_line_index).left_col ? 0 : win_col_off(wp); - } - } - if (virt_line_offset == 0) { - // Skip the column states if there is a "virt_left_col" line. - wlv.draw_state = WL_BRI - 1; - } else if (statuscol.draw) { - // Skip fold, sign and number states if 'statuscolumn' is set. - wlv.draw_state = WL_STC - 1; - } - } + assert(wlv.off == 0); - if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) { - wlv.draw_state = WL_FOLD; - handle_foldcolumn(wp, &wlv); + if (cmdwin_type != 0 && wp == curwin) { + // Draw the cmdline character. + draw_col_fill(&wlv, schar_from_ascii(cmdwin_type), 1, win_hl_attr(wp, HLF_AT)); } - // sign column, this is hit until sign_idx reaches count - if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0) { - // Show the sign column when desired. - wlv.draw_state = WL_SIGN; - if (wp->w_scwidth > 0) { - get_sign_display_info(false, wp, &wlv, sign_idx, sign_cul_attr); - if (++sign_idx < wp->w_scwidth) { - wlv.draw_state = WL_SIGN - 1; - } else { - sign_idx = 0; - } + if (wlv.filler_todo > 0) { + int index = wlv.filler_todo - (wlv.filler_lines - wlv.n_virt_lines); + if (index > 0) { + virt_line_index = (int)kv_size(virt_lines) - index; + assert(virt_line_index >= 0); + virt_line_offset = kv_A(virt_lines, virt_line_index).left_col ? 0 : win_col_off(wp); } } - if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0) { - // Show the line number, if desired. - wlv.draw_state = WL_NR; - handle_lnum_col(wp, &wlv, sign_num_attr, sign_cul_attr); - } - - if (wlv.draw_state == WL_STC - 1 && wlv.n_extra == 0) { - wlv.draw_state = WL_STC; - // Draw the 'statuscolumn' if option is set. - if (statuscol.draw) { - if (sign_num_attr == 0) { - statuscol.num_attr = get_line_number_attr(wp, &wlv); + if (virt_line_offset == 0) { + // skip columns + } else if (statuscol.draw) { + // Draw 'statuscolumn' if it is set. + if (sign_num_attr == 0) { + statuscol.num_attr = get_line_number_attr(wp, &wlv); + } + if (statuscol.textp == NULL) { + v = (ptr - line); + get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol); + if (!end_fill) { + // Get the line again as evaluating 'statuscolumn' may free it. + line = ml_get_buf(wp->w_buffer, lnum); + ptr = line + v; } - if (statuscol.textp == NULL) { - v = (ptr - line); - get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol); - if (!end_fill) { - // Get the line again as evaluating 'statuscolumn' may free it. - line = ml_get_buf(wp->w_buffer, lnum); - ptr = line + v; - } - if (wp->w_redr_statuscol) { - break; - } + if (wp->w_redr_statuscol) { + break; } - get_statuscol_display_info(&statuscol, &wlv); } - } + draw_statuscol(wp, &statuscol, &wlv); + } else { + // draw builtin info columns: fold, sign, number + draw_foldcolumn(wp, &wlv); + + // wp->w_scwidth is zero if signcol=number is used + for (int sign_idx = 0; sign_idx < wp->w_scwidth; sign_idx++) { + draw_sign(false, wp, &wlv, sign_idx, sign_cul_attr); + } - if (wlv.draw_state == WL_STC && wlv.n_extra == 0) { - win_col_offset = wlv.off; + draw_lnum_col(wp, &wlv, sign_num_attr, sign_cul_attr); } + win_col_offset = wlv.off; + // Check if 'breakindent' applies and show it. // May change wlv.draw_state to WL_BRI or WL_BRI - 1. - if (wlv.n_extra == 0) { + if (!wp->w_briopt_sbr) { handle_breakindent(wp, &wlv); } - - if (wlv.draw_state == WL_SBR - 1 && wlv.n_extra == 0) { - wlv.draw_state = WL_SBR; - handle_showbreak_and_filler(wp, &wlv); + handle_showbreak_and_filler(wp, &wlv); + if (wp->w_briopt_sbr) { + handle_breakindent(wp, &wlv); } - if (wlv.draw_state == WL_LINE - 1 && wlv.n_extra == 0) { - sign_idx = 0; - wlv.draw_state = WL_LINE; - if (has_decor && wlv.row == startrow + wlv.filler_lines) { - // hide virt_text on text hidden by 'nowrap' or 'smoothscroll' - decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state); - } - win_line_continue(&wlv); // use wlv.saved_ values + wlv.col = wlv.off; + draw_cols = false; + if (wlv.filler_todo <= 0) { + leftcols_width = wlv.off; + } + if (has_decor && wlv.row == startrow + wlv.filler_lines) { + // hide virt_text on text hidden by 'nowrap' or 'smoothscroll' + decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state); } } - if (cul_screenline && wlv.draw_state == WL_LINE - && wlv.vcol >= left_curline_col - && wlv.vcol < right_curline_col) { + if (cul_screenline && wlv.vcol >= left_curline_col && wlv.vcol < right_curline_col) { apply_cursorline_highlight(wp, &wlv); } @@ -1690,7 +1611,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && wp == curwin && lnum == wp->w_cursor.lnum && wlv.vcol >= wp->w_virtcol) - || (number_only && wlv.draw_state > WL_STC)) + || number_only) && wlv.filler_todo <= 0) { draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row); // don't clear anything after wlv.col @@ -1705,15 +1626,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl break; } - const bool draw_folded = wlv.draw_state == WL_LINE && has_fold - && wlv.row == startrow + wlv.filler_lines; + const bool draw_folded = has_fold && wlv.row == startrow + wlv.filler_lines; if (draw_folded && wlv.n_extra == 0) { wlv.char_attr = folded_attr = win_hl_attr(wp, HLF_FL); } int extmark_attr = 0; - if (wlv.draw_state == WL_LINE - && (area_highlighting || spv->spv_has_spell || extra_check)) { + if (area_highlighting || spv->spv_has_spell || extra_check) { if (wlv.n_extra == 0 || !wlv.extra_for_extmark) { wlv.reset_extra_attr = false; } @@ -1740,7 +1659,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl decor_recheck_draw_col(wlv.off, selected, &decor_state); decor_need_recheck = false; } - extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state); + if (wlv.filler_todo <= 0) { + extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state); + } if (!has_fold && wp->w_buffer->b_virt_text_inline > 0) { handle_inline_virtual_text(wp, &wlv, v); @@ -1924,28 +1845,31 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // Only restore search_attr and area_attr after "n_extra" in // the next screen line is also done. if (wlv.n_extra <= 0) { - if (wlv.saved_n_extra <= 0) { - if (search_attr == 0) { - search_attr = saved_search_attr; - saved_search_attr = 0; - } - if (area_attr == 0 && *ptr != NUL) { - area_attr = saved_area_attr; - saved_area_attr = 0; - } - if (decor_attr == 0) { - decor_attr = saved_decor_attr; - saved_decor_attr = 0; - } + if (search_attr == 0) { + search_attr = saved_search_attr; + saved_search_attr = 0; + } + if (area_attr == 0 && *ptr != NUL) { + area_attr = saved_area_attr; + saved_area_attr = 0; + } + if (decor_attr == 0) { + decor_attr = saved_decor_attr; + saved_decor_attr = 0; + } - if (wlv.extra_for_extmark) { - // wlv.extra_attr should be used at this position but not - // any further. - wlv.reset_extra_attr = true; - } + if (wlv.extra_for_extmark) { + // wlv.extra_attr should be used at this position but not + // any further. + wlv.reset_extra_attr = true; } wlv.extra_for_extmark = false; } + } else if (wlv.filler_todo > 0) { + // Wait with reading text until filler lines are done. Still need to + // initialize these. + mb_c = ' '; + mb_schar = schar_from_ascii(' '); } else if (has_fold) { // skip writing the buffer line itself mb_c = NUL; @@ -2519,7 +2443,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // In the cursor line and we may be concealing characters: correct // the cursor column when we reach its position. - if (!did_wcol && wlv.draw_state == WL_LINE + if (!did_wcol && wp == curwin && lnum == wp->w_cursor.lnum && conceal_cursor_line(wp) && (int)wp->w_virtcol <= wlv.vcol + wlv.skip_cells) { @@ -2530,7 +2454,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } // Don't override visual selection highlighting. - if (wlv.n_attr > 0 && wlv.draw_state == WL_LINE && !search_attr_from_match) { + if (wlv.n_attr > 0 && !search_attr_from_match) { wlv.char_attr = hl_combine_attr(wlv.char_attr, wlv.extra_attr); if (wlv.reset_extra_attr) { wlv.reset_extra_attr = false; @@ -2547,7 +2471,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && wp->w_p_list && (wp->w_p_wrap ? (wp->w_skipcol > 0 && wlv.row == 0) : wp->w_leftcol > 0) && wlv.filler_todo <= 0 - && wlv.draw_state > WL_STC && mb_c != NUL) { mb_c = wp->w_p_lcs_chars.prec; lcs_prec_todo = NUL; @@ -2638,9 +2561,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl wlv.col -= wlv.boguscols; wlv.boguscols = 0; - if (draw_color_col) { - draw_color_col = advance_color_col(VCOL_HLC, &color_cols); - } + advance_color_col(&wlv, vcol_hlc(wlv)); bool has_virttext = false; // Make sure alignment is the same regardless @@ -2653,10 +2574,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } if (((wp->w_p_cuc - && wp->w_virtcol >= VCOL_HLC - eol_hl_off + && wp->w_virtcol >= vcol_hlc(wlv) - eol_hl_off && wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + v && lnum != wp->w_cursor.lnum) - || draw_color_col || wlv.line_attr_lowprio || wlv.line_attr + || wlv.color_cols || wlv.line_attr_lowprio || wlv.line_attr || wlv.diff_hlf != 0 || has_virttext)) { int rightmost_vcol = 0; @@ -2664,11 +2585,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl rightmost_vcol = wp->w_virtcol; } - if (draw_color_col) { + if (wlv.color_cols) { // determine rightmost colorcolumn to possibly draw - for (int i = 0; color_cols[i] >= 0; i++) { - if (rightmost_vcol < color_cols[i]) { - rightmost_vcol = color_cols[i]; + for (int i = 0; wlv.color_cols[i] >= 0; i++) { + if (rightmost_vcol < wlv.color_cols[i]) { + rightmost_vcol = wlv.color_cols[i]; } } } @@ -2693,15 +2614,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl linebuf_char[wlv.off] = schar_from_ascii(' '); linebuf_vcol[wlv.off] = MAXCOL; wlv.col++; - if (draw_color_col) { - draw_color_col = advance_color_col(VCOL_HLC, &color_cols); - } + advance_color_col(&wlv, vcol_hlc(wlv)); int col_attr = base_attr; - if (wp->w_p_cuc && VCOL_HLC == wp->w_virtcol) { + if (wp->w_p_cuc && vcol_hlc(wlv) == wp->w_virtcol) { col_attr = cuc_attr; - } else if (draw_color_col && VCOL_HLC == *color_cols) { + } else if (wlv.color_cols && vcol_hlc(wlv) == *wlv.color_cols) { col_attr = hl_combine_attr(wlv.line_attr_lowprio, mc_attr); } @@ -2710,7 +2629,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl linebuf_attr[wlv.off] = col_attr; wlv.off++; - if (VCOL_HLC >= rightmost_vcol) { + if (vcol_hlc(wlv) >= rightmost_vcol) { break; } @@ -2747,13 +2666,20 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); conceal_cursor_used = conceal_cursor_line(curwin); } + + // When the window is too narrow draw all "@" lines. + if (leftcols_width >= wp->w_grid.cols && wp->w_p_wrap) { + win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT); + set_empty_rows(wp, wlv.row); + wlv.row = endrow; + } + break; } // Show "extends" character from 'listchars' if beyond the line end and // 'list' is set. if (wp->w_p_lcs_chars.ext != NUL - && wlv.draw_state == WL_LINE && wp->w_p_list && !wp->w_p_wrap && wlv.filler_todo <= 0 @@ -2773,47 +2699,38 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } } - // advance to the next 'colorcolumn' - if (draw_color_col) { - draw_color_col = advance_color_col(VCOL_HLC, &color_cols); - } + advance_color_col(&wlv, vcol_hlc(wlv)); // Highlight the cursor column if 'cursorcolumn' is set. But don't // highlight the cursor position itself. // Also highlight the 'colorcolumn' if it is different than // 'cursorcolumn' - // Also highlight the 'colorcolumn' if 'breakindent' and/or 'showbreak' - // options are set vcol_save_attr = -1; - if ((wlv.draw_state == WL_LINE - || wlv.draw_state == WL_BRI - || wlv.draw_state == WL_SBR) - && !lnum_in_visual_area + if (!lnum_in_visual_area && search_attr == 0 && area_attr == 0 && wlv.filler_todo <= 0) { - if (wp->w_p_cuc && VCOL_HLC == wp->w_virtcol + if (wp->w_p_cuc && vcol_hlc(wlv) == wp->w_virtcol && lnum != wp->w_cursor.lnum) { vcol_save_attr = wlv.char_attr; wlv.char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), wlv.char_attr); - } else if (draw_color_col && VCOL_HLC == *color_cols) { + } else if (wlv.color_cols && vcol_hlc(wlv) == *wlv.color_cols) { vcol_save_attr = wlv.char_attr; wlv.char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), wlv.char_attr); } } // Apply lowest-priority line attr now, so everything can override it. - if (wlv.draw_state == WL_LINE) { - wlv.char_attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.char_attr); - } + wlv.char_attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.char_attr); - if (wlv.draw_state == WL_LINE) { - vcol_prev = wlv.vcol; - } + vcol_prev = wlv.vcol; // Store character to be displayed. // Skip characters that are left of the screen for 'nowrap'. - if (wlv.draw_state < WL_LINE || wlv.skip_cells <= 0) { + if (wlv.filler_todo > 0) { + // TODO(bfredl): the main render loop should get called also with the virtual + // lines chunks, so we get line wrapping and other Nice Things. + } else if (wlv.skip_cells <= 0) { // Store the character. linebuf_char[wlv.off] = mb_schar; if (multi_attr) { @@ -2823,18 +2740,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl linebuf_attr[wlv.off] = wlv.char_attr; } - if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) { - linebuf_vcol[wlv.off] = wlv.vcol; - } else if (wlv.draw_state == WL_FOLD) { - if (wlv.n_closing > 0) { - linebuf_vcol[wlv.off] = -3; - wlv.n_closing--; - } else { - linebuf_vcol[wlv.off] = -2; - } - } else { - linebuf_vcol[wlv.off] = -1; - } + linebuf_vcol[wlv.off] = wlv.vcol; if (utf_char2cells(mb_c) > 1) { // Need to fill two screen columns. @@ -2844,11 +2750,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl linebuf_char[wlv.off] = 0; linebuf_attr[wlv.off] = linebuf_attr[wlv.off - 1]; - if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) { - linebuf_vcol[wlv.off] = ++wlv.vcol; - } else { - linebuf_vcol[wlv.off] = -1; - } + linebuf_vcol[wlv.off] = ++wlv.vcol; // When "wlv.tocol" is halfway through a character, set it to the end // of the character, otherwise highlighting won't stop. @@ -2904,15 +2806,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } // The skipped cells need to be accounted for in vcol. - if (wlv.draw_state > WL_STC && wlv.skipped_cells > 0) { + if (wlv.skipped_cells > 0) { wlv.vcol += wlv.skipped_cells; wlv.skipped_cells = 0; } // Only advance the "wlv.vcol" when after the 'number' or // 'relativenumber' column. - if (wlv.draw_state > WL_STC - && wlv.filler_todo <= 0) { + if (wlv.filler_todo <= 0) { wlv.vcol++; } @@ -2921,12 +2822,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } // restore attributes after "predeces" in 'listchars' - if (wlv.draw_state > WL_STC && n_attr3 > 0 && --n_attr3 == 0) { + if (n_attr3 > 0 && --n_attr3 == 0) { wlv.char_attr = saved_attr3; } // restore attributes after last 'listchars' or 'number' char - if (wlv.n_attr > 0 && wlv.draw_state == WL_LINE && --wlv.n_attr == 0) { + if (wlv.n_attr > 0 && --wlv.n_attr == 0) { wlv.char_attr = saved_attr2; } @@ -2947,8 +2848,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // At end of screen line and there is more to come: Display the line // so far. If there is no more to display it is caught above. if (wlv.col >= grid->cols && (!has_fold || virt_line_offset >= 0) - && (wlv.draw_state != WL_LINE - || *ptr != NUL + && (*ptr != NUL || wlv.filler_todo > 0 || (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL && wlv.p_extra != at_end_str) @@ -2992,7 +2892,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } // When the window is too narrow draw all "@" lines. - if (wlv.draw_state != WL_LINE && wlv.filler_todo <= 0) { + if (wlv.col <= leftcols_width) { win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT); set_empty_rows(wp, wlv.row); wlv.row = endrow; @@ -3005,6 +2905,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } win_line_start(wp, &wlv, true); + draw_cols = true; lcs_prec_todo = wp->w_p_lcs_chars.prec; if (wlv.filler_todo <= 0) { diff --git a/src/nvim/sign.c b/src/nvim/sign.c index b52142f721..41ec4572ee 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -27,6 +27,7 @@ #include "nvim/fold.h" #include "nvim/gettext.h" #include "nvim/globals.h" +#include "nvim/grid.h" #include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/macros_defs.h" @@ -105,7 +106,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr DecorSignHighlight sign = DECOR_SIGN_HIGHLIGHT_INIT; sign.flags |= kSHIsSign; - sign.text.ptr = sp->sn_text ? xstrdup(sp->sn_text) : NULL; + memcpy(sign.text, sp->sn_text, SIGN_WIDTH * sizeof(schar_T)); sign.sign_name = xstrdup(sp->sn_name); sign.hl_id = sp->sn_text_hl; sign.line_hl_id = sp->sn_line_hl; @@ -114,7 +115,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr sign.priority = (DecorPriority)prio; bool has_hl = (sp->sn_line_hl || sp->sn_num_hl || sp->sn_cul_hl); - uint16_t decor_flags = (sp->sn_text ? MT_FLAG_DECOR_SIGNTEXT : 0) + uint16_t decor_flags = (sp->sn_text[0] ? MT_FLAG_DECOR_SIGNTEXT : 0) | (has_hl ? MT_FLAG_DECOR_SIGNHL : 0); DecorInline decor = { .ext = true, .data.ext = { .vt = NULL, .sh_idx = decor_put_sh(sign) } }; @@ -334,9 +335,24 @@ static int sign_cmd_idx(char *begin_cmd, char *end_cmd) return idx; } +/// buf must be SIGN_WIDTH * MAX_SCHAR_SIZE (no extra +1 needed) +size_t describe_sign_text(char *buf, schar_T *sign_text) +{ + size_t p = 0; + for (int i = 0; i < SIGN_WIDTH; i++) { + schar_get(buf + p, sign_text[i]); + size_t len = strlen(buf + p); + if (len == 0) { + break; + } + p += len; + } + return p; +} + /// Initialize the "text" for a new sign and store in "sign_text". /// "sp" is NULL for signs added through nvim_buf_set_extmark(). -int init_sign_text(sign_T *sp, char **sign_text, char *text) +int init_sign_text(sign_T *sp, schar_T *sign_text, char *text) { char *s; char *endp = text + (int)strlen(text); @@ -351,34 +367,29 @@ int init_sign_text(sign_T *sp, char **sign_text, char *text) // Count cells and check for non-printable chars int cells = 0; for (s = text; s < endp; s += utfc_ptr2len(s)) { - if (!vim_isprintc(utf_ptr2char(s))) { + int c; + sign_text[cells] = utfc_ptr2schar(s, &c); + if (!vim_isprintc(c)) { break; } - cells += utf_ptr2cells(s); + int width = utf_char2cells(c); + if (width == 2) { + sign_text[cells + 1] = 0; + } + cells += width; } // Currently must be empty, one or two display cells - if (s != endp || cells > 2) { + if (s != endp || cells > SIGN_WIDTH) { if (sp != NULL) { semsg(_("E239: Invalid sign text: %s"), text); } return FAIL; } - if (cells < 1) { - if (sp != NULL) { - sp->sn_text = NULL; - } - return OK; - } - if (sp != NULL) { - xfree(sp->sn_text); - } - // Allocate one byte more if we need to pad up with a space. - size_t len = (size_t)(endp - text + (cells == 1)); - *sign_text = xstrnsave(text, len); - - if (cells == 1) { - STRCPY(*sign_text + len - 1, " "); + if (cells < 1) { + sign_text[0] = 0; + } else if (cells == 1) { + sign_text[1] = schar_from_ascii(' '); } return OK; @@ -412,7 +423,7 @@ static int sign_define_by_name(char *name, char *icon, char *text, char *linehl, backslash_halve((*sp)->sn_icon); } - if (text != NULL && (init_sign_text(*sp, &(*sp)->sn_text, text) == FAIL)) { + if (text != NULL && (init_sign_text(*sp, (*sp)->sn_text, text) == FAIL)) { return FAIL; } @@ -437,7 +448,6 @@ static int sign_undefine_by_name(const char *name) } xfree(sp->sn_name); - xfree(sp->sn_text); xfree(sp->sn_icon); xfree(sp); return OK; @@ -452,9 +462,11 @@ static void sign_list_defined(sign_T *sp) msg_outtrans(sp->sn_icon, 0); msg_puts(_(" (not supported)")); } - if (sp->sn_text != NULL) { + if (sp->sn_text[0]) { msg_puts(" text="); - msg_outtrans(sp->sn_text, 0); + char buf[SIGN_WIDTH * MAX_SCHAR_SIZE]; + describe_sign_text(buf, sp->sn_text); + msg_outtrans(buf, 0); } static char *arg[] = { " linehl=", " texthl=", " culhl=", " numhl=" }; int hl[] = { sp->sn_line_hl, sp->sn_text_hl, sp->sn_cul_hl, sp->sn_num_hl }; @@ -881,8 +893,10 @@ static dict_T *sign_get_info_dict(sign_T *sp) if (sp->sn_icon != NULL) { tv_dict_add_str(d, S_LEN("icon"), sp->sn_icon); } - if (sp->sn_text != NULL) { - tv_dict_add_str(d, S_LEN("text"), sp->sn_text); + if (sp->sn_text[0]) { + char buf[SIGN_WIDTH * MAX_SCHAR_SIZE]; + describe_sign_text(buf, sp->sn_text); + tv_dict_add_str(d, S_LEN("text"), buf); } static char *arg[] = { "linehl", "texthl", "culhl", "numhl" }; int hl[] = { sp->sn_line_hl, sp->sn_text_hl, sp->sn_cul_hl, sp->sn_num_hl }; diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 79d21585fc..7676fa5319 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -1,8 +1,10 @@ #pragma once +#include "nvim/types_defs.h" + /// Sign attributes. Used by the screen refresh routines. typedef struct { - char *text; + schar_T text[SIGN_WIDTH]; int hl_id; } SignTextAttrs; @@ -10,13 +12,12 @@ typedef struct { typedef struct sign { char *sn_name; // name of sign char *sn_icon; // name of pixmap - char *sn_text; // text used instead of pixmap + schar_T sn_text[SIGN_WIDTH]; // text used instead of pixmap int sn_line_hl; // highlight ID for line int sn_text_hl; // highlight ID for text int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set int sn_num_hl; // highlight ID for line number } sign_T; -enum { SIGN_WIDTH = 2, }; ///< Number of display cells for a sign in the signcolumn enum { SIGN_SHOW_MAX = 9, }; ///< Maximum number of signs shown on a single line enum { SIGN_DEF_PRIO = 10, }; ///< Default sign highlight priority diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 01729bc4de..b0d3988ce6 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1641,20 +1641,32 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op char *p = NULL; if (fold) { - size_t n = fill_foldcolumn(out_p, wp, stcp->foldinfo, - (linenr_T)get_vim_var_nr(VV_LNUM), NULL); + schar_T fold_buf[10]; + size_t n = fill_foldcolumn(NULL, wp, stcp->foldinfo, + (linenr_T)get_vim_var_nr(VV_LNUM), 0, fold_buf); stl_items[curitem].minwid = -((stcp->use_cul ? HLF_CLF : HLF_FC) + 1); + size_t buflen = 0; + // TODO(bfredl): this is very backwards. we must support schar_T + // being used directly in 'statuscol' + for (size_t i = 0; i < n; i++) { + schar_get(out_p + buflen, fold_buf[i]); + buflen += strlen(out_p + buflen); + } p = out_p; - p[n] = NUL; } + char buf[SIGN_WIDTH * MAX_SCHAR_SIZE]; size_t buflen = 0; varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM); for (int i = 0; i < width; i++) { if (!fold) { SignTextAttrs *sattr = virtnum ? NULL : &stcp->sattrs[i]; - p = sattr && sattr->text ? sattr->text : " "; - stl_items[curitem].minwid = -(sattr && sattr->text + p = " "; + if (sattr && sattr->text[0]) { + describe_sign_text(buf, sattr->text); + p = buf; + } + stl_items[curitem].minwid = -(sattr && sattr->text[0] ? (stcp->sign_cul_id ? stcp->sign_cul_id : sattr->hl_id) : (stcp->use_cul ? HLF_CLS : HLF_SC) + 1); } diff --git a/src/nvim/types_defs.h b/src/nvim/types_defs.h index cc9deb9630..81845eecdb 100644 --- a/src/nvim/types_defs.h +++ b/src/nvim/types_defs.h @@ -56,6 +56,8 @@ typedef struct { } SignRange; #define SIGNRANGE_INIT { 0, 0 } +enum { SIGN_WIDTH = 2, }; ///< Number of display cells for a sign in the signcolumn + typedef struct file_buffer buf_T; typedef struct syn_state synstate_T; typedef struct terminal Terminal; -- cgit From 19aba5916a4064b503894185072fb1c47a41e023 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 22 Dec 2023 10:55:39 +0100 Subject: docs(options): add codeblock annotations to options.lua (#26696) Also consistently remove leading colons in examples Co-authored-by: zeertzjq --- src/nvim/options.lua | 526 +++++++++++++++++++++++++-------------------------- 1 file changed, 263 insertions(+), 263 deletions(-) (limited to 'src') diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 43c938b0bf..d599e0452d 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -254,8 +254,8 @@ return { from before it was deleted. When it appears again then it is read. |timestamp| If this option has a local value, use this command to switch back to - using the global value: > - :set autoread< + using the global value: >vim + set autoread< < ]=], full_name = 'autoread', @@ -324,10 +324,10 @@ return { be undone. First delete the "g:colors_name" variable when needed. Normally this option would be set in the vimrc file. Possibly - depending on the terminal name. Example: > - :if $TERM ==# "xterm" - : set background=dark - :endif + depending on the terminal name. Example: >vim + if $TERM ==# "xterm" + set background=dark + endif < When this option is changed, the default settings for the highlight groups will change. To use other settings, place ":highlight" commands AFTER the setting of the 'background' option. @@ -496,12 +496,12 @@ return { use '//', instead of '\\'. - Environment variables are expanded |:set_env|. - Careful with '\' characters, type one before a space, type two to - get one in the option (see |option-backslash|), for example: > - :set bdir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces + get one in the option (see |option-backslash|), for example: >vim + set bdir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces < See also 'backup' and 'writebackup' options. - If you want to hide your backup files on Unix, consider this value: > - :set backupdir=./.backup,~/.backup,.,/tmp + If you want to hide your backup files on Unix, consider this value: >vim + set backupdir=./.backup,~/.backup,.,/tmp < You must create a ".backup" directory in each directory and in your home directory for this to work properly. The use of |:set+=| and |:set-=| is preferred when adding or removing @@ -533,8 +533,8 @@ return { If you like to keep a lot of backups, you could use a BufWritePre autocommand to change 'backupext' just before writing the file to - include a timestamp. > - :au BufWritePre * let &bex = '-' .. strftime("%Y%b%d%X") .. '~' + include a timestamp. >vim + au BufWritePre * let &bex = '-' .. strftime("%Y%b%d%X") .. '~' < Use 'backupdir' to put the backup in a different directory. ]=], full_name = 'backupext', @@ -571,7 +571,7 @@ return { Note that environment variables are not expanded. If you want to use $HOME you must expand it explicitly, e.g.: >vim - :let &backupskip = escape(expand('$HOME'), '\') .. '/tmp/*' + let &backupskip = escape(expand('$HOME'), '\') .. '/tmp/*' < Note that the default also makes sure that "crontab -e" works (when a backup would be made by renaming the original file crontab won't see @@ -969,8 +969,8 @@ return { in the current directory first. If the default value taken from $CDPATH is not what you want, include a modified version of the following command in your vimrc file to - override it: > - :let &cdpath = ',' .. substitute(substitute($CDPATH, '[, ]', '\\\0', 'g'), ':', ',', 'g') + override it: >vim + let &cdpath = ',' .. substitute(substitute($CDPATH, '[, ]', '\\\0', 'g'), ':', ',', 'g') < This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. (parts of 'cdpath' can be passed to the shell to expand file names). @@ -995,9 +995,9 @@ return { The key used in Command-line Mode to open the command-line window. Only non-printable keys are allowed. The key can be specified as a single character, but it is difficult to - type. The preferred way is to use the <> notation. Examples: > - :exe "set cedit=\\" - :exe "set cedit=\\" + type. The preferred way is to use the <> notation. Examples: >vim + exe "set cedit=\\" + exe "set cedit=\\" < |Nvi| also has this option, but it only uses the first character. See |cmdwin|. ]=], @@ -1043,7 +1043,7 @@ return { Conversion between "latin1", "unicode", "ucs-2", "ucs-4" and "utf-8" is done internally by Vim, 'charconvert' is not used for this. Also used for Unicode conversion. - Example: > + Example: >vim set charconvert=CharConvert() fun CharConvert() system("recode " @@ -1134,7 +1134,7 @@ return { desc = [=[ Keywords that are interpreted as a C++ scope declaration by |cino-g|. Useful e.g. for working with the Qt framework that defines additional - scope declarations "signals", "public slots" and "private slots": > + scope declarations "signals", "public slots" and "private slots": >vim set cinscopedecls+=signals,public\ slots,private\ slots < ]=], @@ -1251,11 +1251,11 @@ return { highlighted with ColorColumn |hl-ColorColumn|. Useful to align text. Will make screen redrawing slower. The screen column can be an absolute number, or a number preceded with - '+' or '-', which is added to or subtracted from 'textwidth'. > + '+' or '-', which is added to or subtracted from 'textwidth'. >vim - :set cc=+1 " highlight column after 'textwidth' - :set cc=+1,+2,+3 " highlight three columns after 'textwidth' - :hi ColorColumn ctermbg=lightgrey guibg=lightgrey + set cc=+1 " highlight column after 'textwidth' + set cc=+1,+2,+3 " highlight three columns after 'textwidth' + hi ColorColumn ctermbg=lightgrey guibg=lightgrey < When 'textwidth' is zero then the items with '-' and '+' are not used. A maximum of 256 columns are highlighted. @@ -1283,8 +1283,8 @@ return { number of columns of the display, the display may be messed up. For the GUI it is always possible and Vim limits the number of columns to what fits on the screen. You can use this command to get the widest - window possible: > - :set columns=9999 + window possible: >vim + set columns=9999 < Minimum value is 12, maximum value is 10000. ]=], full_name = 'columns', @@ -1361,8 +1361,8 @@ return { k scan the files given with the 'dictionary' option kspell use the currently active spell checking |spell| k{dict} scan the file {dict}. Several "k" flags can be given, - patterns are valid too. For example: > - :set cpt=k/usr/dict/*,k~/spanish + patterns are valid too. For example: >vim + set cpt=k/usr/dict/*,k~/spanish < s scan the files given with the 'thesaurus' option s{tsr} scan the file {tsr}. Several "s" flags can be given, patterns are valid too. @@ -1855,7 +1855,7 @@ return { |hl-CursorColumn|. Useful to align text. Will make screen redrawing slower. If you only want the highlighting in the current window you can use - these autocommands: > + these autocommands: >vim au WinLeave * set nocursorline nocursorcolumn au WinEnter * set cursorline cursorcolumn < @@ -1952,7 +1952,7 @@ return { < If the function is defined with `func_name : function() {...`: > ^\s*\ze\i\+\s*[:]\s*(*function\s*( < When using the ":set" command, you need to double the backslashes! - To avoid that use `:let` with a single quote string: > + To avoid that use `:let` with a single quote string: >vim let &l:define = '^\s*\ze\k\+\s*=\s*function(' < ]=], @@ -2159,11 +2159,11 @@ return { patience patience diff algorithm histogram histogram diff algorithm - Examples: > - :set diffopt=internal,filler,context:4 - :set diffopt= - :set diffopt=internal,filler,foldcolumn:3 - :set diffopt-=internal " do NOT use the internal diff parser + Examples: >vim + set diffopt=internal,filler,context:4 + set diffopt= + set diffopt=internal,filler,foldcolumn:3 + set diffopt-=internal " do NOT use the internal diff parser < ]=], expand_cb = 'expand_set_diffopt', @@ -2224,8 +2224,8 @@ return { - A directory name may end in an ':' or '/'. - Environment variables are expanded |:set_env|. - Careful with '\' characters, type one before a space, type two to - get one in the option (see |option-backslash|), for example: > - :set dir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces + get one in the option (see |option-backslash|), for example: >vim + set dir=c:\\tmp,\ dir\\,with\\,commas,\\\ dir\ with\ spaces < Editing the same file twice will result in a warning. Using "/tmp" on is discouraged: if the system crashes you lose the swap file. And @@ -2495,8 +2495,8 @@ return { A list of autocommand event names, which are to be ignored. When set to "all" or when "all" is one of the items, all autocommand events are ignored, autocommands will not be executed. - Otherwise this is a comma-separated list of event names. Example: > - :set ei=WinEnter,WinLeave + Otherwise this is a comma-separated list of event names. Example: >vim + set ei=WinEnter,WinLeave < ]=], expand_cb = 'expand_set_eventignore', @@ -2616,7 +2616,7 @@ return { will work and the first entry of 'fileencodings' will be used (except "ucs-bom", which requires the BOM to be present). If you prefer another encoding use an BufReadPost autocommand event to test if your - preferred encoding is to be used. Example: > + preferred encoding is to be used. Example: >vim au BufReadPost * if search('\S', 'w') == 0 | \ set fenc=iso-2022-jp | endif < This sets 'fileencoding' to "iso-2022-jp" if the file does not contain @@ -2624,8 +2624,8 @@ return { When the |++enc| argument is used then the value of 'fileencodings' is not used. Note that 'fileencodings' is not used for a new file, the global value - of 'fileencoding' is used instead. You can set it with: > - :setglobal fenc=iso-8859-2 + of 'fileencoding' is used instead. You can set it with: >vim + setglobal fenc=iso-8859-2 < This means that a non-existing file may get a different encoding than an empty file. The special value "ucs-bom" can be used to check for a Unicode BOM @@ -2789,11 +2789,11 @@ return { this use the ":filetype on" command. |:filetype| Setting this option to a different value is most useful in a modeline, for a file for which the file type is not automatically recognized. - Example, for in an IDL file: > + Example, for in an IDL file: >c /* vim: set filetype=idl : */ < |FileType| |filetypes| When a dot appears in the value then this separates two filetype - names. Example: > + names. Example: >c /* vim: set filetype=c.doxygen : */ < This will use the "c" filetype first, then the "doxygen" filetype. This works both for filetype plugins and for syntax files. More than @@ -2853,8 +2853,8 @@ return { "vert", "vertleft", "vertright", "verthoriz", "foldsep" and "fold" default to single-byte alternatives. - Example: > - :set fillchars=stl:\ ,stlnc:\ ,vert:│,fold:·,diff:- + Example: >vim + set fillchars=stl:\ ,stlnc:\ ,vert:│,fold:·,diff:- < For the "stl", "stlnc", "foldopen", "foldclose" and "foldsep" items single-byte and multibyte characters are supported. But double-width @@ -3208,8 +3208,8 @@ return { automatic formatting. This can be empty. Don't insert it yet! - Example: > - :set formatexpr=mylang#Format() + Example: >vim + set formatexpr=mylang#Format() < This will invoke the mylang#Format() function in the autoload/mylang.vim file in 'runtimepath'. |autoload| @@ -3223,7 +3223,7 @@ return { the internal format mechanism. If the expression starts with s: or ||, then it is replaced with - the script ID (|local-function|). Example: > + the script ID (|local-function|). Example: >vim set formatexpr=s:MyFormatExpr() set formatexpr=SomeFormatExpr() < Otherwise, the expression is evaluated in the context of the script @@ -3390,8 +3390,8 @@ return { will be included. Environment variables are expanded |:set_env|. See |option-backslash| about including spaces and backslashes. When your "grep" accepts the "-H" argument, use this to make ":grep" - also work well with a single file: > - :set grepprg=grep\ -nH + also work well with a single file: >vim + set grepprg=grep\ -nH < Special value: When 'grepprg' is set to "internal" the |:grep| command works like |:vimgrep|, |:lgrep| like |:lvimgrep|, |:grepadd| like |:vimgrepadd| and |:lgrepadd| like |:lvimgrepadd|. @@ -3417,11 +3417,11 @@ return { Configures the cursor style for each mode. Works in the GUI and many terminals. See |tui-cursor-shape|. - To disable cursor-styling, reset the option: > - :set guicursor= + To disable cursor-styling, reset the option: >vim + set guicursor= - < To enable mode shapes, "Cursor" highlight, and blinking: > - :set guicursor=n-v-c:block,i-ci-ve:ver25,r-cr:hor20,o:hor50 + < To enable mode shapes, "Cursor" highlight, and blinking: >vim + set guicursor=n-v-c:block,i-ci-ve:ver25,r-cr:hor20,o:hor50 \,a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor \,sm:block-blinkwait175-blinkoff150-blinkon175 @@ -3454,8 +3454,8 @@ return { the cursor starts blinking, blinkon is the time that the cursor is shown and blinkoff is the time that the cursor is not shown. Times are in msec. When one of - the numbers is zero, there is no blinking. E.g.: > - :set guicursor=n:blinkon0 + the numbers is zero, there is no blinking. E.g.: >vim + set guicursor=n:blinkon0 < - Default is "blinkon0" for each mode. {group-name} Highlight group that decides the color and font of the @@ -3493,9 +3493,9 @@ return { to do a common setting for all modes. For example, to switch off blinking: "a:blinkon0" - Examples of cursor highlighting: > - :highlight Cursor gui=reverse guifg=NONE guibg=NONE - :highlight Cursor gui=NONE guifg=bg guibg=fg + Examples of cursor highlighting: >vim + highlight Cursor gui=reverse guifg=NONE guibg=NONE + highlight Cursor gui=NONE guifg=bg guibg=fg < ]=], full_name = 'guicursor', @@ -3519,8 +3519,8 @@ return { Spaces after a comma are ignored. To include a comma in a font name precede it with a backslash. Setting an option requires an extra backslash before a space and a backslash. See also - |option-backslash|. For example: > - :set guifont=Screen15,\ 7x13,font\\,with\\,commas + |option-backslash|. For example: >vim + set guifont=Screen15,\ 7x13,font\\,with\\,commas < will make Vim try to use the font "Screen15" first, and if it fails it will try to use "7x13" and then "font,with,commas" instead. @@ -3531,14 +3531,14 @@ return { the case of X). The font names given should be "normal" fonts. Vim will try to find the related bold and italic fonts. - For Win32 and Mac OS: > - :set guifont=* + For Win32 and Mac OS: >vim + set guifont=* < will bring up a font requester, where you can pick the font you want. The font name depends on the GUI used. - For Mac OSX you can use something like this: > - :set guifont=Monaco:h10 + For Mac OSX you can use something like this: >vim + set guifont=Monaco:h10 < *E236* Note that the fonts must be mono-spaced (all characters have the same width). @@ -3563,9 +3563,9 @@ return { Use a ':' to separate the options. - A '_' can be used in the place of a space, so you don't need to use backslashes to escape the spaces. - - Examples: > - :set guifont=courier_new:h12:w5:b:cRUSSIAN - :set guifont=Andale_Mono:h7.5:w4.5 + - Examples: >vim + set guifont=courier_new:h12:w5:b:cRUSSIAN + set guifont=Andale_Mono:h7.5:w4.5 < ]=], deny_duplicates = true, @@ -3745,8 +3745,8 @@ return { When non-empty describes the text to use in a tooltip for the GUI tab pages line. When empty Vim will use a default tooltip. This option is otherwise just like 'guitablabel' above. - You can include a line break. Simplest method is to use |:let|: > - :let &guitabtooltip = "line one\nline two" + You can include a line break. Simplest method is to use |:let|: >vim + let &guitabtooltip = "line one\nline two" < ]=], enable_if = false, @@ -3814,8 +3814,8 @@ return { be used as a last resort. You can add "en" to prefer English over another language, but that will only find tags that exist in that language and not in the English help. - Example: > - :set helplang=de,it + Example: >vim + set helplang=de,it < This will first search German, then Italian and finally English help files. When using |CTRL-]| and ":help!" in a non-English help file Vim will @@ -4031,8 +4031,8 @@ return { 1 :lmap is ON and IM is off 2 :lmap is off and IM is ON To always reset the option to zero when leaving Insert mode with - this can be used: > - :inoremap :set iminsert=0 + this can be used: >vim + inoremap :set iminsert=0 < This makes :lmap and IM turn off automatically when leaving Insert mode. Note that this option changes when using CTRL-^ in Insert mode @@ -4125,20 +4125,20 @@ return { defaults = { if_true = '' }, desc = [=[ Expression to be used to transform the string found with the 'include' - option to a file name. Mostly useful to change "." to "/" for Java: > - :setlocal includeexpr=substitute(v:fname,'\\.','/','g') + option to a file name. Mostly useful to change "." to "/" for Java: >vim + setlocal includeexpr=substitute(v:fname,'\\.','/','g') < The "v:fname" variable will be set to the file name that was detected. Note the double backslash: the `:set` command first halves them, then one remains in the value, where "\." matches a dot literally. For - simple character replacements `tr()` avoids the need for escaping: > - :setlocal includeexpr=tr(v:fname,'.','/') + simple character replacements `tr()` avoids the need for escaping: >vim + setlocal includeexpr=tr(v:fname,'.','/') < Also used for the |gf| command if an unmodified file name can't be found. Allows doing "gf" on the name after an 'include' statement. Also used for ||. If the expression starts with s: or ||, then it is replaced with - the script ID (|local-function|). Example: > + the script ID (|local-function|). Example: >vim setlocal includeexpr=s:MyIncludeExpr(v:fname) setlocal includeexpr=SomeIncludeExpr(v:fname) < Otherwise, the expression is evaluated in the context of the script @@ -4180,7 +4180,7 @@ return { typing a search command. See also: 'hlsearch'. If you don't want to turn 'hlsearch' on, but want to highlight all matches while searching, you can turn on and off 'hlsearch' with - autocmd. Example: > + autocmd. Example: >vim augroup vimrc-incsearch-highlight autocmd! autocmd CmdlineEnter /,\? :set hlsearch @@ -4217,7 +4217,7 @@ return { when the expression is evaluated (but it may be moved around). If the expression starts with s: or ||, then it is replaced with - the script ID (|local-function|). Example: > + the script ID (|local-function|). Example: >vim set indentexpr=s:MyIndentExpr() set indentexpr=SomeIndentExpr() < Otherwise, the expression is evaluated in the context of the script @@ -4231,8 +4231,8 @@ return { The evaluation of the expression must not have side effects! It must not change the text, jump to another window, etc. Afterwards the cursor position is always restored, thus the cursor may be moved. - Normally this option would be set to call a function: > - :set indentexpr=GetMyIndent() + Normally this option would be set to call a function: >vim + set indentexpr=GetMyIndent() < Error messages will be suppressed, unless the 'debug' option contains "msg". See |indent-expression|. @@ -4560,9 +4560,9 @@ return { When "man" or "man -s" is used, Vim will automatically translate a [count] for the "K" command to a section number. See |option-backslash| about including spaces and backslashes. - Example: > - :set keywordprg=man\ -s - :set keywordprg=:Man + Example: >vim + set keywordprg=man\ -s + set keywordprg=:Man < This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. ]=], @@ -4593,10 +4593,10 @@ return { This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. - Example (for Greek, in UTF-8): *greek* > - :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz - < Example (exchanges meaning of z and y for commands): > - :set langmap=zy,yz,ZY,YZ + Example (for Greek, in UTF-8): *greek* >vim + set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz + < Example (exchanges meaning of z and y for commands): >vim + set langmap=zy,yz,ZY,YZ < The 'langmap' option is a list of parts, separated with commas. Each part can be in one of two forms: @@ -4634,22 +4634,22 @@ return { defaults = { if_true = '' }, desc = [=[ Language to use for menu translation. Tells which file is loaded - from the "lang" directory in 'runtimepath': > + from the "lang" directory in 'runtimepath': >vim "lang/menu_" .. &langmenu .. ".vim" < (without the spaces). For example, to always use the Dutch menus, no - matter what $LANG is set to: > - :set langmenu=nl_NL.ISO_8859-1 + matter what $LANG is set to: >vim + set langmenu=nl_NL.ISO_8859-1 < When 'langmenu' is empty, |v:lang| is used. Only normal file name characters can be used, `/\*?[|<>` are illegal. If your $LANG is set to a non-English language but you do want to use - the English menus: > - :set langmenu=none + the English menus: >vim + set langmenu=none < This option must be set before loading menus, switching on filetype detection or syntax highlighting. Once the menus are defined setting - this option has no effect. But you could do this: > - :source $VIMRUNTIME/delmenu.vim - :set langmenu=de_DE.ISO_8859-1 - :source $VIMRUNTIME/menu.vim + this option has no effect. But you could do this: >vim + source $VIMRUNTIME/delmenu.vim + set langmenu=de_DE.ISO_8859-1 + source $VIMRUNTIME/menu.vim < Warning: This deletes all menus that you defined yourself! ]=], full_name = 'langmenu', @@ -4756,8 +4756,8 @@ return { option will cause the window size to be changed. When you only want to use the size for the GUI, put the command in your |gvimrc| file. Vim limits the number of lines to what fits on the screen. You can - use this command to get the tallest window possible: > - :set lines=999 + use this command to get the tallest window possible: >vim + set lines=999 < Minimum value is 2, maximum value is 1000. ]=], full_name = 'lines', @@ -4859,8 +4859,8 @@ return { The cursor is displayed at the start of the space a Tab character occupies, not at the end as usual in Normal mode. To get this cursor - position while displaying Tabs with spaces, use: > - :set list lcs=tab:\ \ + position while displaying Tabs with spaces, use: >vim + set list lcs=tab:\ \ < Note that list mode will also affect formatting (set with 'textwidth' or 'wrapmargin') when 'cpoptions' includes 'L'. See 'listchars' for @@ -4924,8 +4924,8 @@ return { lead:c Character to show for leading spaces. When omitted, leading spaces are blank. Overrides the "space" and "multispace" settings for leading spaces. You can - combine it with "tab:", for example: > - :set listchars+=tab:>-,lead:. + combine it with "tab:", for example: >vim + set listchars+=tab:>-,lead:. < *lcs-leadmultispace* leadmultispace:c... @@ -4961,17 +4961,17 @@ return { The characters ':' and ',' should not be used. UTF-8 characters can be used. All characters must be single width. - Each character can be specified as hex: > + Each character can be specified as hex: >vim set listchars=eol:\\x24 set listchars=eol:\\u21b5 set listchars=eol:\\U000021b5 < Note that a double backslash is used. The number of hex characters must be exactly 2 for \\x, 4 for \\u and 8 for \\U. - Examples: > - :set lcs=tab:>-,trail:- - :set lcs=tab:>-,eol:<,nbsp:% - :set lcs=extends:>,precedes:< + Examples: >vim + set lcs=tab:>-,trail:- + set lcs=tab:>-,eol:<,nbsp:% + set lcs=extends:>,precedes:< < |hl-NonText| highlighting will be used for "eol", "extends" and "precedes". |hl-Whitespace| for "nbsp", "space", "tab", "multispace", "lead" and "trail". @@ -5055,8 +5055,8 @@ return { This would be mostly useful when you use MS-Windows. If iconv is enabled, setting 'makeencoding' to "char" has the same effect as - setting to the system locale encoding. Example: > - :set makeencoding=char " system locale is used + setting to the system locale encoding. Example: >vim + set makeencoding=char " system locale is used < ]=], expand_cb = 'expand_set_encoding', @@ -5078,11 +5078,11 @@ return { about including spaces and backslashes. Note that a '|' must be escaped twice: once for ":set" and once for the interpretation of a command. When you use a filter called - "myfilter" do it like this: > - :set makeprg=gmake\ \\\|\ myfilter + "myfilter" do it like this: >vim + set makeprg=gmake\ \\\|\ myfilter < The placeholder "$*" can be given (even multiple times) to specify - where the arguments will be included, for example: > - :set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*} + where the arguments will be included, for example: >vim + set makeprg=latex\ \\\\nonstopmode\ \\\\input\\{$*} < This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. ]=], @@ -5107,12 +5107,12 @@ return { jump between two double quotes. The characters must be separated by a colon. The pairs must be separated by a comma. Example for including '<' and - '>' (for HTML): > - :set mps+=<:> + '>' (for HTML): >vim + set mps+=<:> < A more exotic example, to jump between the '=' and ';' in an - assignment, useful for languages like C and Java: > - :au FileType c,cpp,java set mps+==:; + assignment, useful for languages like C and Java: >vim + au FileType c,cpp,java set mps+==:; < For a more advanced way of using "%", see the matchit.vim plugin in the $VIMRUNTIME/plugin directory. |add-local-help| @@ -5253,8 +5253,8 @@ return { The languages for which these numbers are important are Italian and Hungarian. The default works for when you have about 512 Mbyte. If - you have 1 Gbyte you could use: > - :set mkspellmem=900000,3000,800 + you have 1 Gbyte you could use: >vim + set mkspellmem=900000,3000,800 < If you have less than 512 Mbyte |:mkspell| may fail for some languages, no matter what you set 'mkspellmem' to. @@ -5388,8 +5388,8 @@ return { defaults = { if_true = 'nvi' }, desc = [=[ Enables mouse support. For example, to enable the mouse in Normal mode - and Visual mode: > - :set mouse=nv + and Visual mode: >vim + set mouse=nv < To temporarily disable mouse support, hold the shift key while using the mouse. @@ -5499,19 +5499,19 @@ return { Note that you can further refine the meaning of buttons with mappings. See |mouse-overview|. But mappings are NOT used for modeless selection. - Example: > - :map - :map - :map - :map <2-S-LeftMouse> <2-RightMouse> - :map <2-S-LeftDrag> <2-RightDrag> - :map <2-S-LeftRelease> <2-RightRelease> - :map <3-S-LeftMouse> <3-RightMouse> - :map <3-S-LeftDrag> <3-RightDrag> - :map <3-S-LeftRelease> <3-RightRelease> - :map <4-S-LeftMouse> <4-RightMouse> - :map <4-S-LeftDrag> <4-RightDrag> - :map <4-S-LeftRelease> <4-RightRelease> + Example: >vim + map + map + map + map <2-S-LeftMouse> <2-RightMouse> + map <2-S-LeftDrag> <2-RightDrag> + map <2-S-LeftRelease> <2-RightRelease> + map <3-S-LeftMouse> <3-RightMouse> + map <3-S-LeftDrag> <3-RightDrag> + map <3-S-LeftRelease> <3-RightRelease> + map <4-S-LeftMouse> <4-RightMouse> + map <4-S-LeftDrag> <4-RightDrag> + map <4-S-LeftRelease> <4-RightRelease> < Mouse commands requiring the CTRL modifier can be simulated by typing the "g" key before using the mouse: @@ -5559,8 +5559,8 @@ return { for vertical scrolling). You can disable mouse scrolling by using a count of 0. - Example: > - :set mousescroll=ver:5,hor:2 + Example: >vim + set mousescroll=ver:5,hor:2 < Will make Nvim scroll 5 lines at a time when scrolling vertically, and scroll 2 columns at a time when scrolling horizontally. ]=], @@ -5636,8 +5636,8 @@ return { Any modes not specified or shapes not available use the normal mouse pointer. - Example: > - :set mouseshape=s:udsizing,m:no + Example: >vim + set mouseshape=s:udsizing,m:no < will make the mouse turn to a sizing arrow over the status lines and indicate no input when the hit-enter prompt is displayed (since clicking the mouse has no effect in this state.) @@ -5935,30 +5935,30 @@ return { provided that the file being searched for has a relative path (not starting with "/", "./" or "../"). The directories in the 'path' option may be relative or absolute. - - Use commas to separate directory names: > - :set path=.,/usr/local/include,/usr/include + - Use commas to separate directory names: >vim + set path=.,/usr/local/include,/usr/include < - Spaces can also be used to separate directory names. To have a space in a directory name, precede it with an extra backslash, and - escape the space: > - :set path=.,/dir/with\\\ space + escape the space: >vim + set path=.,/dir/with\\\ space < - To include a comma in a directory name precede it with an extra - backslash: > - :set path=.,/dir/with\\,comma - < - To search relative to the directory of the current file, use: > - :set path=. + backslash: >vim + set path=.,/dir/with\\,comma + < - To search relative to the directory of the current file, use: >vim + set path=. < - To search in the current directory use an empty string between two - commas: > - :set path=,, + commas: >vim + set path=,, < - A directory name may end in a ':' or '/'. - Environment variables are expanded |:set_env|. - When using |netrw.vim| URLs can be used. For example, adding "https://www.vim.org" will make ":find index.html" work. - Search upwards and downwards in a directory tree using "*", "**" and ";". See |file-searching| for info and syntax. - - Careful with '\' characters, type two to get one in the option: > - :set path=.,c:\\include - < Or just use '/' instead: > - :set path=.,c:/include + - Careful with '\' characters, type two to get one in the option: >vim + set path=.,c:\\include + < Or just use '/' instead: >vim + set path=.,c:/include < Don't forget "." or files won't even be found in the same directory as the file! The maximum length is limited. How much depends on the system, mostly @@ -5967,14 +5967,14 @@ return { 'path', see |:checkpath|. The use of |:set+=| and |:set-=| is preferred when adding or removing directories from the list. This avoids problems when a future version - uses another default. To remove the current directory use: > - :set path-= - < To add the current directory use: > - :set path+= + uses another default. To remove the current directory use: >vim + set path-= + < To add the current directory use: >vim + set path+= < To use an environment variable, you probably need to replace the separator. Here is an example to append $INCL, in which directory - names are separated with a semi-colon: > - :let &path = &path .. "," .. substitute($INCL, ';', ',', 'g') + names are separated with a semi-colon: >vim + let &path = &path .. "," .. substitute($INCL, ';', ',', 'g') < Replace the ';' with a ':' or whatever separator is used. Note that this doesn't work when $INCL contains a comma or white space. ]=], @@ -6059,10 +6059,10 @@ return { It is possible to override the level for individual highlights within the popupmenu using |highlight-blend|. For instance, to enable - transparency but force the current selected element to be fully opaque: > + transparency but force the current selected element to be fully opaque: >vim - :set pumblend=15 - :hi PmenuSel blend=0 + set pumblend=15 + hi PmenuSel blend=0 < UI-dependent. Works best with RGB colors. 'termguicolors' ]=], @@ -6422,8 +6422,8 @@ return { The default ruler width is 17 characters. To make the ruler 15 characters wide, put "%15(" at the start and "%)" at the end. - Example: > - :set rulerformat=%15(%c%V\ %p%%%) + Example: >vim + set rulerformat=%15(%c%V\ %p%%%) < ]=], full_name = 'rulerformat', @@ -6516,8 +6516,8 @@ return { runtime files. For speed, use as few items as possible and avoid wildcards. See |:runtime|. - Example: > - :set runtimepath=~/vimruntime,/mygroup/vim,$VIMRUNTIME + Example: >vim + set runtimepath=~/vimruntime,/mygroup/vim,$VIMRUNTIME < This will use the directory "~/vimruntime" first (containing your personal Nvim runtime files), then "/mygroup/vim", and finally "$VIMRUNTIME" (the default runtime files). @@ -6630,7 +6630,7 @@ return { in the middle of the window (except at the start or end of the file or when long lines wrap). After using the local value, go back the global value with one of - these two: > + these two: >vim setlocal scrolloff< setlocal scrolloff=-1 < For scrolling horizontally see 'sidescrolloff'. @@ -6910,8 +6910,8 @@ return { 2^8 < 10240 < 2^16) + 10240 bytes (requested maximum item contents size) = 10253 bytes. - Example: > - :set shada='50,<1000,s100,:0,n~/nvim/shada + Example: >vim + set shada='50,<1000,s100,:0,n~/nvim/shada < '50 Marks will be remembered for the last 50 files you edited. @@ -6982,12 +6982,12 @@ return { Environment variables are expanded |:set_env|. If the name of the shell contains a space, you need to enclose it in - quotes. Example with quotes: > - :set shell=\"c:\program\ files\unix\sh.exe\"\ -f + quotes. Example with quotes: >vim + set shell=\"c:\program\ files\unix\sh.exe\"\ -f < Note the backslash before each quote (to avoid starting a comment) and each space (to avoid ending the option value), so better use |:let-&| - like this: > - :let &shell='"C:\Program Files\unix\sh.exe" -f' + like this: >vim + let &shell='"C:\Program Files\unix\sh.exe" -f' < Also note that the "-f" is not inside the quotes, because it is not part of the command name. *shell-unquoting* @@ -7010,7 +7010,7 @@ return { Note that such processing is done after |:set| did its own round of unescaping, so to keep yourself sane use |:let-&| like shown above. *shell-powershell* - To use PowerShell: > + To use PowerShell: >vim let &shell = executable('pwsh') ? 'pwsh' : 'powershell' let &shellcmdflag = '-NoLogo -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new();$PSDefaultParameterValues[''Out-File:Encoding'']=''utf8'';Remove-Alias -Force -ErrorAction SilentlyContinue tee;' let &shellredir = '2>&1 | %%{ "$_" } | Out-File %s; exit $LastExitCode' @@ -7181,7 +7181,7 @@ return { existing file names, thus this option needs to be set before opening any file for best results. This might change in the future. 'shellslash' only works when a backslash can be used as a path - separator. To test if this is so use: > + separator. To test if this is so use: >vim if exists('+shellslash') < Also see 'completeslash'. ]=], @@ -7357,9 +7357,9 @@ return { defaults = { if_true = '' }, desc = [=[ String to put at the start of lines that have been wrapped. Useful - values are "> " or "+++ ": > - :let &showbreak = "> " - :let &showbreak = '+++ ' + values are "> " or "+++ ": >vim + let &showbreak = "> " + let &showbreak = '+++ ' < Only printable single-cell characters are allowed, excluding and comma (in a future version the comma might be used to separate the part that is shown at the end and at the start of a line). @@ -7368,8 +7368,8 @@ return { If you want the 'showbreak' to appear in between line numbers, add the "n" flag to 'cpoptions'. A window-local value overrules a global value. If the global value is - set and you want no value in the current window use NONE: > - :setlocal showbreak=NONE + set and you want no value in the current window use NONE: >vim + setlocal showbreak=NONE < ]=], full_name = 'showbreak', @@ -7535,16 +7535,16 @@ return { horizontally centered in the window, as long as one does not come too close to the beginning of the line. After using the local value, go back the global value with one of - these two: > + these two: >vim setlocal sidescrolloff< setlocal sidescrolloff=-1 < Example: Try this together with 'sidescroll' and 'listchars' as in the following example to never allow the cursor to move - onto the "extends" character: > + onto the "extends" character: >vim - :set nowrap sidescroll=1 listchars=extends:>,precedes:< - :set sidescrolloff=1 + set nowrap sidescroll=1 listchars=extends:>,precedes:< + set sidescrolloff=1 < ]=], full_name = 'sidescrolloff', @@ -7780,7 +7780,7 @@ return { deny_duplicates = true, desc = [=[ A comma-separated list of word list names. When the 'spell' option is - on spellchecking will be done for these languages. Example: > + on spellchecking will be done for these languages. Example: >vim set spelllang=en_us,nl,medical < This means US English, Dutch and medical words are recognized. Words that are not recognized will be highlighted. @@ -7914,8 +7914,8 @@ return { 'verbose' option to a non-zero value. Only one of "best", "double" or "fast" may be used. The others may - appear several times in any order. Example: > - :set sps=file:~/.config/nvim/sugg,best,expr:MySuggest() + appear several times in any order. Example: >vim + set sps=file:~/.config/nvim/sugg,best,expr:MySuggest() < This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. @@ -8039,21 +8039,21 @@ return { Examples: >vim " Relative number with bar separator and click handlers: - :set statuscolumn=%@SignCb@%s%=%T%@NumCb@%r│%T + set statuscolumn=%@SignCb@%s%=%T%@NumCb@%r│%T " Right aligned relative cursor line number: - :let &stc='%=%{v:relnum?v:relnum:v:lnum} ' + let &stc='%=%{v:relnum?v:relnum:v:lnum} ' " Line numbers in hexadecimal for non wrapped part of lines: - :let &stc='%=%{v:virtnum>0?"":printf("%x",v:lnum)} ' + let &stc='%=%{v:virtnum>0?"":printf("%x",v:lnum)} ' " Human readable line numbers with thousands separator: - :let &stc='%{substitute(v:lnum,"\\d\\zs\\ze\\' + let &stc='%{substitute(v:lnum,"\\d\\zs\\ze\\' . '%(\\d\\d\\d\\)\\+$",",","g")}' " Both relative and absolute line numbers with different " highlighting for odd and even relative numbers: - :let &stc='%#NonText#%{&nu?v:lnum:""}' . + let &stc='%#NonText#%{&nu?v:lnum:""}' . '%=%{&rnu&&(v:lnum%2)?"\ ".v:relnum:""}' . '%#LineNr#%{&rnu&&!(v:lnum%2)?"\ ".v:relnum:""}' @@ -8083,8 +8083,8 @@ return { be given as "%%". When the option starts with "%!" then it is used as an expression, - evaluated and the result is used as the option value. Example: > - :set statusline=%!MyStatusLine() + evaluated and the result is used as the option value. Example: >vim + set statusline=%!MyStatusLine() < The *g:statusline_winid* variable will be set to the |window-ID| of the window that the status line belongs to. The result can contain %{} items that will be evaluated too. @@ -8165,7 +8165,7 @@ return { return value of expr contains "%" items they will get expanded. The expression can contain the "}" character, the end of expression is denoted by "%}". - For example: > + For example: >vim func! Stl_filename() abort return "%t" endfunc @@ -8232,8 +8232,8 @@ return { When all items in a group becomes an empty string (i.e. flags that are not set) and a minwid is not set for the group, the whole group will become empty. This will make a group like the following disappear - completely from the statusline when none of the flags are set. > - :set statusline=...%(\ [%M%R%H]%)... + completely from the statusline when none of the flags are set. >vim + set statusline=...%(\ [%M%R%H]%)... < Beware that an expression is evaluated each and every time the status line is displayed. *stl-%{* *g:actual_curbuf* *g:actual_curwin* @@ -8264,23 +8264,23 @@ return { edit your vimrc or whatever with "vim --clean" to get it right. Examples: - Emulate standard status line with 'ruler' set > - :set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P - < Similar, but add ASCII value of char under the cursor (like "ga") > - :set statusline=%<%f%h%m%r%=%b\ 0x%B\ \ %l,%c%V\ %P - < Display byte count and byte value, modified flag in red. > - :set statusline=%<%f%=\ [%1*%M%*%n%R%H]\ %-19(%3l,%02c%03V%)%O'%02b' - :hi User1 term=inverse,bold cterm=inverse,bold ctermfg=red - < Display a ,GZ flag if a compressed file is loaded > - :set statusline=...%r%{VarExists('b:gzflag','\ [GZ]')}%h... - < In the |:autocmd|'s: > - :let b:gzflag = 1 - < And: > - :unlet b:gzflag - < And define this function: > - :function VarExists(var, val) - : if exists(a:var) | return a:val | else | return '' | endif - :endfunction + Emulate standard status line with 'ruler' set >vim + set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P + < Similar, but add ASCII value of char under the cursor (like "ga") >vim + set statusline=%<%f%h%m%r%=%b\ 0x%B\ \ %l,%c%V\ %P + < Display byte count and byte value, modified flag in red. >vim + set statusline=%<%f%=\ [%1*%M%*%n%R%H]\ %-19(%3l,%02c%03V%)%O'%02b' + hi User1 term=inverse,bold cterm=inverse,bold ctermfg=red + < Display a ,GZ flag if a compressed file is loaded >vim + set statusline=...%r%{VarExists('b:gzflag','\ [GZ]')}%h... + < In the |:autocmd|'s: >vim + let b:gzflag = 1 + < And: >vim + unlet b:gzflag + < And define this function: >vim + function VarExists(var, val) + if exists(a:var) | return a:val | else | return '' | endif + endfunction < ]=], full_name = 'statusline', @@ -8322,8 +8322,8 @@ return { deny_duplicates = true, desc = [=[ Comma-separated list of suffixes, which are used when searching for a - file for the "gf", "[I", etc. commands. Example: > - :set suffixesadd=.java + file for the "gf", "[I", etc. commands. Example: >vim + set suffixesadd=.java < ]=], full_name = 'suffixesadd', @@ -8433,19 +8433,19 @@ return { Otherwise this option does not always reflect the current syntax (the b:current_syntax variable does). This option is most useful in a modeline, for a file which syntax is - not automatically recognized. Example, in an IDL file: > + not automatically recognized. Example, in an IDL file: >c /* vim: set syntax=idl : */ < When a dot appears in the value then this separates two filetype - names. Example: > + names. Example: >c /* vim: set syntax=c.doxygen : */ < This will use the "c" syntax first, then the "doxygen" syntax. Note that the second one must be prepared to be loaded as an addition, otherwise it will be skipped. More than one dot may appear. - To switch off syntax highlighting for the current file, use: > - :set syntax=OFF + To switch off syntax highlighting for the current file, use: >vim + set syntax=OFF < To switch syntax highlighting on according to the current value of the - 'filetype' option: > - :set syntax=ON + 'filetype' option: >vim + set syntax=ON < What actually happens when setting the 'syntax' option is that the Syntax autocommand event is triggered with the value as argument. This option is not copied to another buffer, independent of the 's' or @@ -9014,13 +9014,13 @@ return { expanded according to the rules used for 'statusline'. This option cannot be set in a modeline when 'modelineexpr' is off. - Example: > - :auto BufEnter * let &titlestring = hostname() .. "/" .. expand("%:p") - :set title titlestring=%<%F%=%l/%L-%P titlelen=70 + Example: >vim + auto BufEnter * let &titlestring = hostname() .. "/" .. expand("%:p") + set title titlestring=%<%F%=%l/%L-%P titlelen=70 < The value of 'titlelen' is used to align items in the middle or right of the available space. - Some people prefer to have the file name first: > - :set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:~:.:h\")})%)%(\ %a%) + Some people prefer to have the file name first: >vim + set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:~:.:h\")})%)%(\ %a%) < Note the use of "%{ }" and an expression to get the path of the file, without the file name. The "%( %)" constructs are used to add a separating space only when needed. @@ -9146,13 +9146,13 @@ return { is kept in memory, higher numbers will cause more memory to be used. Nevertheless, a single change can already use a large amount of memory. Set to 0 for Vi compatibility: One level of undo and "u" undoes - itself: > + itself: >vim set ul=0 < But you can also get Vi compatibility by including the 'u' flag in 'cpoptions', and still be able to use CTRL-R to repeat undo. Also see |undo-two-ways|. Set to -1 for no undo at all. You might want to do this only for the - current buffer: > + current buffer: >vim setlocal ul=-1 < This helps when you run out of memory for a single change. @@ -9238,8 +9238,8 @@ return { For example, when editing assembly language files where statements start in the 9th column and comments in the 41st, it may be useful - to use the following: > - :set varsofttabstop=8,32,8 + to use the following: >vim + set varsofttabstop=8,32,8 < This will set soft tabstops with 8 and 8 + 32 spaces, and 8 more for every column thereafter. @@ -9260,8 +9260,8 @@ return { desc = [=[ A list of the number of spaces that a in the file counts for, separated by commas. Each value corresponds to one tab, with the - final value applying to all subsequent tabs. For example: > - :set vartabstop=4,20,10,8 + final value applying to all subsequent tabs. For example: >vim + set vartabstop=4,20,10,8 < This will make the first tab 4 spaces wide, the second 20 spaces, the third 10 spaces, and all following tabs 8 spaces. @@ -9463,8 +9463,8 @@ return { ~ "~" Normal [ Insert and Replace ] Insert and Replace - For example: > - :set ww=<,>,[,] + For example: >vim + set ww=<,>,[,] < allows wrap only when cursor keys are used. When the movement keys are used in combination with a delete or change operator, the also counts for a character. This makes "3h" @@ -9501,8 +9501,8 @@ return { Some keys will not work, such as CTRL-C, and Enter. can be used, but hitting it twice in a row will still exit command-line as a failsafe measure. - Although 'wc' is a number option, you can set it to a special key: > - :set wc= + Although 'wc' is a number option, you can set it to a special key: >vim + set wc= < ]=], full_name = 'wildchar', @@ -9520,9 +9520,9 @@ return { recognized when used inside a macro. You can find "spare" command-line keys suitable for this option by looking at |ex-edit-index|. Normally you'll never actually type 'wildcharm', just use it in mappings that - automatically invoke completion mode, e.g.: > - :set wcm= - :cnoremap ss so $vim/sessions/*.vim + automatically invoke completion mode, e.g.: >vim + set wcm= + cnoremap ss so $vim/sessions/*.vim < Then after typing :ss you can use CTRL-P & CTRL-N. ]=], full_name = 'wildcharm', @@ -9542,8 +9542,8 @@ return { |globpath()| unless a flag is passed to disable this. The pattern is used like with |:autocmd|, see |autocmd-pattern|. Also see 'suffixes'. - Example: > - :set wildignore=*.o,*.obj + Example: >vim + set wildignore=*.o,*.obj < The use of |:set+=| and |:set-=| is preferred when adding or removing a pattern from the list. This avoids problems when a future version uses another default. @@ -9606,9 +9606,9 @@ return { completion. If you want and to move the cursor instead of selecting - a different match, use this: > - :cnoremap - :cnoremap + a different match, use this: >vim + cnoremap + cnoremap < |hl-WildMenu| highlights the current match. ]=], @@ -9655,16 +9655,16 @@ return { and sort buffers by time last used (other than the current buffer). - Examples: > - :set wildmode=full - < Complete first full match, next match, etc. (the default) > - :set wildmode=longest,full - < Complete longest common string, then each full match > - :set wildmode=list:full - < List all matches and complete each full match > - :set wildmode=list,full - < List all matches without completing, then each full match > - :set wildmode=longest,list + Examples: >vim + set wildmode=full + < Complete first full match, next match, etc. (the default) >vim + set wildmode=longest,full + < Complete longest common string, then each full match >vim + set wildmode=list:full + < List all matches and complete each full match >vim + set wildmode=list,full + < List all matches without completing, then each full match >vim + set wildmode=longest,list < Complete longest common string, then list alternatives. More info here: |cmdline-completion|. ]=], @@ -9848,7 +9848,7 @@ return { Other windows will be only 'winminheight' high. This has the drawback that ":all" will create only two windows. To avoid "vim -o 1 2 3 4" to create only two windows, set the option after startup is done, - using the |VimEnter| event: > + using the |VimEnter| event: >vim au VimEnter * set winheight=999 < Minimum value is 1. The height is not adjusted after one of the commands that change the @@ -9884,7 +9884,7 @@ return { the popupmenu are determined by the current window. Highlights in the message area cannot be overridden. - Example: show a different color for non-current windows: > + Example: show a different color for non-current windows: >vim set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC < ]=], @@ -9974,9 +9974,9 @@ return { horizontally. The line will be broken in the middle of a word if necessary. See 'linebreak' to get the break at a word boundary. - To make scrolling horizontally a bit more useful, try this: > - :set sidescroll=5 - :set listchars+=precedes:<,extends:> + To make scrolling horizontally a bit more useful, try this: >vim + set sidescroll=5 + set listchars+=precedes:<,extends:> < See 'sidescroll', 'listchars' and |wrap-off|. This option can't be set from a |modeline| when the 'diff' option is on. -- cgit From 35d98888bdeb0d0ac805887ecda149c9788c5a9f Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Fri, 22 Dec 2023 12:07:15 +0100 Subject: refactor(drawline): simplify draw_statuscol() and remove draw_state references --- src/nvim/drawline.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 29221e64f9..134e81b4b0 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -663,7 +663,6 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T } /// Get information needed to display the next segment in the 'statuscolumn'. -/// If not yet at the end, prepare for next segment and decrement "wlv->draw_state". /// /// @param stcp Status column attributes /// @param[in,out] wlv @@ -671,22 +670,19 @@ static void draw_statuscol(win_T *wp, statuscol_T *stcp, winlinevars_T *wlv) { do { int attr = stcp->cur_attr; - char *text = stcp->textp; - char *section_end = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end; - ptrdiff_t len = section_end - text; + char *start = stcp->textp; + stcp->textp = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end; + ptrdiff_t len = stcp->textp - start; // Prepare for next highlight section if not yet at the end - if (section_end < stcp->text_end) { + if (stcp->textp < stcp->text_end) { int hl = stcp->hlrecp->userhl; - stcp->textp = stcp->hlrecp->start; stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr; stcp->hlrecp++; - } else { - stcp->textp = section_end; } // Skip over empty highlight sections if (len) { static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * SIGN_WIDTH) * MB_MAXBYTES + 1]; - size_t translen = transstr_buf(text, len, transbuf, sizeof transbuf, true); + size_t translen = transstr_buf(start, len, transbuf, sizeof transbuf, true); draw_col_buf(wp, wlv, transbuf, translen, attr, false); } } while (stcp->textp < stcp->text_end); @@ -1582,7 +1578,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl win_col_offset = wlv.off; // Check if 'breakindent' applies and show it. - // May change wlv.draw_state to WL_BRI or WL_BRI - 1. if (!wp->w_briopt_sbr) { handle_breakindent(wp, &wlv); } -- cgit From 2b0acacb3c2cdd67436846d5117ae323ea7a8fd4 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 19 Dec 2023 13:55:02 +0000 Subject: fix(decor): allow adding providers during redraw Fixes: #26652 --- src/nvim/api/extmark.c | 2 +- src/nvim/decoration_defs.h | 11 +++- src/nvim/decoration_provider.c | 121 +++++++++++++++++------------------------ src/nvim/drawline.c | 4 +- src/nvim/drawscreen.c | 27 ++++----- 5 files changed, 72 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index fa3c5afcc6..b2ddef1a43 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -1050,7 +1050,7 @@ void nvim_set_decoration_provider(Integer ns_id, Dict(set_decoration_provider) * *v = LUA_NOREF; } - p->active = true; + p->state = kDecorProviderActive; p->hl_valid++; p->hl_cached = false; } diff --git a/src/nvim/decoration_defs.h b/src/nvim/decoration_defs.h index 4550ae0a42..d75a7bc242 100644 --- a/src/nvim/decoration_defs.h +++ b/src/nvim/decoration_defs.h @@ -124,7 +124,14 @@ typedef struct { typedef struct { NS ns_id; - bool active; + + enum { + kDecorProviderActive = 1, + kDecorProviderWinDisabled = 2, + kDecorProviderRedrawDisabled = 3, + kDecorProviderDisabled = 4, + } state; + LuaRef redraw_start; LuaRef redraw_buf; LuaRef redraw_win; @@ -137,5 +144,3 @@ typedef struct { uint8_t error_count; } DecorProvider; - -typedef kvec_withinit_t(DecorProvider *, 4) DecorProviders; diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c index e160a563f3..6a7ecf102d 100644 --- a/src/nvim/decoration_provider.c +++ b/src/nvim/decoration_provider.c @@ -26,7 +26,7 @@ enum { DP_MAX_ERROR = 3, }; static kvec_t(DecorProvider) decor_providers = KV_INITIAL_VALUE; #define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \ - { ns_id, false, LUA_NOREF, LUA_NOREF, \ + { ns_id, kDecorProviderDisabled, LUA_NOREF, LUA_NOREF, \ LUA_NOREF, LUA_NOREF, LUA_NOREF, \ LUA_NOREF, -1, false, false, 0 } @@ -37,7 +37,9 @@ static void decor_provider_error(DecorProvider *provider, const char *name, cons msg_schedule_semsg_multiline("Error in decoration provider %s.%s:\n%s", ns_name, name, msg); } -static bool decor_provider_invoke(DecorProvider *provider, const char *name, LuaRef ref, Array args, +// Note we pass in a provider index as this function may cause decor_providers providers to be +// reallocated so we need to be careful with DecorProvider pointers +static bool decor_provider_invoke(int provider_idx, const char *name, LuaRef ref, Array args, bool default_true) { Error err = ERROR_INIT; @@ -48,6 +50,10 @@ static bool decor_provider_invoke(DecorProvider *provider, const char *name, Lua provider_active = false; textlock--; + // We get the provider here via an index in case the above call to nlua_call_ref causes + // decor_providers to be reallocated. + DecorProvider *provider = &kv_A(decor_providers, provider_idx); + if (!ERROR_SET(&err) && api_object_to_bool(ret, "provider %s retval", default_true, &err)) { provider->error_count = 0; @@ -59,7 +65,7 @@ static bool decor_provider_invoke(DecorProvider *provider, const char *name, Lua provider->error_count++; if (provider->error_count >= DP_MAX_ERROR) { - provider->active = false; + provider->state = kDecorProviderDisabled; } } @@ -72,11 +78,7 @@ void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int e { for (size_t i = 0; i < kv_size(decor_providers); i++) { DecorProvider *p = &kv_A(decor_providers, i); - if (!p->active) { - continue; - } - - if (p->spell_nav != LUA_NOREF) { + if (p->state != kDecorProviderDisabled && p->spell_nav != LUA_NOREF) { MAXSIZE_TEMP_ARRAY(args, 6); ADD_C(args, INTEGER_OBJ(wp->handle)); ADD_C(args, INTEGER_OBJ(wp->w_buffer->handle)); @@ -84,7 +86,7 @@ void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int e ADD_C(args, INTEGER_OBJ(start_col)); ADD_C(args, INTEGER_OBJ(end_row)); ADD_C(args, INTEGER_OBJ(end_col)); - decor_provider_invoke(p, "spell", p->spell_nav, args, true); + decor_provider_invoke((int)i, "spell", p->spell_nav, args, true); } } } @@ -93,27 +95,15 @@ void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int e /// /// @param[out] providers Decoration providers /// @param[out] err Provider err -void decor_providers_start(DecorProviders *providers) +void decor_providers_start(void) { - kvi_init(*providers); - for (size_t i = 0; i < kv_size(decor_providers); i++) { DecorProvider *p = &kv_A(decor_providers, i); - if (!p->active) { - continue; - } - - bool active; - if (p->redraw_start != LUA_NOREF) { + if (p->state != kDecorProviderDisabled && p->redraw_start != LUA_NOREF) { MAXSIZE_TEMP_ARRAY(args, 2); ADD_C(args, INTEGER_OBJ((int)display_tick)); - active = decor_provider_invoke(p, "start", p->redraw_start, args, true); - } else { - active = true; - } - - if (active) { - kvi_push(*providers, p); + bool active = decor_provider_invoke((int)i, "start", p->redraw_start, args, true); + kv_A(decor_providers, i).state = active ? kDecorProviderActive : kDecorProviderRedrawDisabled; } } } @@ -125,10 +115,8 @@ void decor_providers_start(DecorProviders *providers) /// @param providers Decoration providers /// @param[out] line_providers Enabled line providers to invoke in win_line /// @param[out] err Provider error -void decor_providers_invoke_win(win_T *wp, DecorProviders *providers, - DecorProviders *line_providers) +void decor_providers_invoke_win(win_T *wp) { - kvi_init(*line_providers); // this might change in the future // then we would need decor_state.running_decor_provider just like "on_line" below assert(kv_size(decor_state.active) == 0); @@ -138,17 +126,21 @@ void decor_providers_invoke_win(win_T *wp, DecorProviders *providers, ? wp->w_botline : MAX(wp->w_topline + wp->w_height_inner, wp->w_botline))); - for (size_t k = 0; k < kv_size(*providers); k++) { - DecorProvider *p = kv_A(*providers, k); - if (p && p->redraw_win != LUA_NOREF) { + for (size_t i = 0; i < kv_size(decor_providers); i++) { + DecorProvider *p = &kv_A(decor_providers, i); + if (p->state == kDecorProviderWinDisabled) { + p->state = kDecorProviderActive; + } + + if (p->state == kDecorProviderActive && p->redraw_win != LUA_NOREF) { MAXSIZE_TEMP_ARRAY(args, 4); ADD_C(args, WINDOW_OBJ(wp->handle)); ADD_C(args, BUFFER_OBJ(wp->w_buffer->handle)); // TODO(bfredl): we are not using this, but should be first drawn line? ADD_C(args, INTEGER_OBJ(wp->w_topline - 1)); ADD_C(args, INTEGER_OBJ(knownmax - 1)); - if (decor_provider_invoke(p, "win", p->redraw_win, args, true)) { - kvi_push(*line_providers, p); + if (!decor_provider_invoke((int)i, "win", p->redraw_win, args, true)) { + kv_A(decor_providers, i).state = kDecorProviderWinDisabled; } } } @@ -161,21 +153,21 @@ void decor_providers_invoke_win(win_T *wp, DecorProviders *providers, /// @param row Row to invoke line callback for /// @param[out] has_decor Set when at least one provider invokes a line callback /// @param[out] err Provider error -void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row, bool *has_decor) +void decor_providers_invoke_line(win_T *wp, int row, bool *has_decor) { decor_state.running_decor_provider = true; - for (size_t k = 0; k < kv_size(*providers); k++) { - DecorProvider *p = kv_A(*providers, k); - if (p && p->redraw_line != LUA_NOREF) { + for (size_t i = 0; i < kv_size(decor_providers); i++) { + DecorProvider *p = &kv_A(decor_providers, i); + if (p->state == kDecorProviderActive && p->redraw_line != LUA_NOREF) { MAXSIZE_TEMP_ARRAY(args, 3); ADD_C(args, WINDOW_OBJ(wp->handle)); ADD_C(args, BUFFER_OBJ(wp->w_buffer->handle)); ADD_C(args, INTEGER_OBJ(row)); - if (decor_provider_invoke(p, "line", p->redraw_line, args, true)) { + if (decor_provider_invoke((int)i, "line", p->redraw_line, args, true)) { *has_decor = true; } else { // return 'false' or error: skip rest of this window - kv_A(*providers, k) = NULL; + kv_A(decor_providers, i).state = kDecorProviderWinDisabled; } hl_check_ns(); @@ -189,15 +181,15 @@ void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row, /// @param buf Buffer /// @param providers Decoration providers /// @param[out] err Provider error -void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers) +void decor_providers_invoke_buf(buf_T *buf) { - for (size_t i = 0; i < kv_size(*providers); i++) { - DecorProvider *p = kv_A(*providers, i); - if (p && p->redraw_buf != LUA_NOREF) { + for (size_t i = 0; i < kv_size(decor_providers); i++) { + DecorProvider *p = &kv_A(decor_providers, i); + if (p->state == kDecorProviderActive && p->redraw_buf != LUA_NOREF) { MAXSIZE_TEMP_ARRAY(args, 2); ADD_C(args, BUFFER_OBJ(buf->handle)); ADD_C(args, INTEGER_OBJ((int64_t)display_tick)); - decor_provider_invoke(p, "buf", p->redraw_buf, args, true); + decor_provider_invoke((int)i, "buf", p->redraw_buf, args, true); } } } @@ -207,14 +199,15 @@ void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers) /// @param providers Decoration providers /// @param displaytick Display tick /// @param[out] err Provider error -void decor_providers_invoke_end(DecorProviders *providers) +void decor_providers_invoke_end(void) { - for (size_t i = 0; i < kv_size(*providers); i++) { - DecorProvider *p = kv_A(*providers, i); - if (p && p->active && p->redraw_end != LUA_NOREF) { + for (size_t i = 0; i < kv_size(decor_providers); i++) { + DecorProvider *p = &kv_A(decor_providers, i); + if (p->state != kDecorProviderDisabled && p->redraw_end != LUA_NOREF) { MAXSIZE_TEMP_ARRAY(args, 1); ADD_C(args, INTEGER_OBJ((int)display_tick)); - decor_provider_invoke(p, "end", p->redraw_end, args, true); + decor_provider_invoke((int)i, "end", p->redraw_end, args, true); + kv_A(decor_providers, i).state = kDecorProviderActive; } } decor_check_to_be_deleted(); @@ -227,10 +220,8 @@ void decor_providers_invoke_end(DecorProviders *providers) /// like highlight_changed() (throttled to the next redraw or mode change) void decor_provider_invalidate_hl(void) { - size_t len = kv_size(decor_providers); - for (size_t i = 0; i < len; i++) { - DecorProvider *item = &kv_A(decor_providers, i); - item->hl_cached = false; + for (size_t i = 0; i < kv_size(decor_providers); i++) { + kv_A(decor_providers, i).hl_cached = false; } if (ns_hl_active) { @@ -242,14 +233,11 @@ void decor_provider_invalidate_hl(void) DecorProvider *get_decor_provider(NS ns_id, bool force) { assert(ns_id > 0); - size_t i; size_t len = kv_size(decor_providers); - for (i = 0; i < len; i++) { - DecorProvider *item = &kv_A(decor_providers, i); - if (item->ns_id == ns_id) { - return item; - } else if (item->ns_id > ns_id) { - break; + for (size_t i = 0; i < len; i++) { + DecorProvider *p = &kv_A(decor_providers, i); + if (p->ns_id == ns_id) { + return p; } } @@ -257,16 +245,7 @@ DecorProvider *get_decor_provider(NS ns_id, bool force) return NULL; } - // Adding a new provider, so allocate room in the vector - (void)kv_a(decor_providers, len); - if (i < len) { - // New ns_id needs to be inserted between existing providers to maintain - // ordering, so shift other providers with larger ns_id - memmove(&kv_A(decor_providers, i + 1), - &kv_A(decor_providers, i), - (len - i) * sizeof(kv_a(decor_providers, i))); - } - DecorProvider *item = &kv_a(decor_providers, i); + DecorProvider *item = &kv_a(decor_providers, len); *item = DECORATION_PROVIDER_INIT(ns_id); return item; @@ -283,7 +262,7 @@ void decor_provider_clear(DecorProvider *p) NLUA_CLEAR_REF(p->redraw_line); NLUA_CLEAR_REF(p->redraw_end); NLUA_CLEAR_REF(p->spell_nav); - p->active = false; + p->state = kDecorProviderDisabled; } void decor_free_all_mem(void) diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 134e81b4b0..e34c22d907 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -945,7 +945,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra) /// /// @return the number of last row the line occupies. int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_only, spellvars_T *spv, - foldinfo_T foldinfo, DecorProviders *providers) + foldinfo_T foldinfo) { winlinevars_T wlv; // variables passed between functions @@ -1081,7 +1081,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl has_decor = decor_redraw_line(wp, lnum - 1, &decor_state); - decor_providers_invoke_line(wp, providers, lnum - 1, &has_decor); + decor_providers_invoke_line(wp, lnum - 1, &has_decor); if (has_decor) { extra_check = true; diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index a6e483ab54..21e8438367 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -552,8 +552,7 @@ int update_screen(void) ui_comp_set_screen_valid(true); - DecorProviders providers; - decor_providers_start(&providers); + decor_providers_start(); // "start" callback could have changed highlights for global elements if (win_check_ns_hl(NULL)) { @@ -600,7 +599,7 @@ int update_screen(void) } if (buf->b_mod_tick_decor < display_tick) { - decor_providers_invoke_buf(buf, &providers); + decor_providers_invoke_buf(buf); buf->b_mod_tick_decor = display_tick; } } @@ -630,7 +629,7 @@ int update_screen(void) did_one = true; start_search_hl(); } - win_update(wp, &providers); + win_update(wp); } // redraw status line and window bar after the window to minimize cursor movement @@ -671,8 +670,7 @@ int update_screen(void) } did_intro = true; - decor_providers_invoke_end(&providers); - kvi_destroy(providers); + decor_providers_invoke_end(); // either cmdline is cleared, not drawn or mode is last drawn cmdline_was_last_drawn = false; @@ -1427,7 +1425,7 @@ static void draw_sep_connectors_win(win_T *wp) /// top: from first row to top_end (when scrolled down) /// mid: from mid_start to mid_end (update inversion or changed text) /// bot: from bot_start to last row (when scrolled up) -static void win_update(win_T *wp, DecorProviders *providers) +static void win_update(win_T *wp) { int top_end = 0; // Below last row of the top area that needs // updating. 0 when no top area updating. @@ -1494,8 +1492,7 @@ static void win_update(win_T *wp, DecorProviders *providers) decor_redraw_reset(wp, &decor_state); - DecorProviders line_providers; - decor_providers_invoke_win(wp, providers, &line_providers); + decor_providers_invoke_win(wp); if (win_redraw_signcols(wp)) { wp->w_lines_valid = 0; @@ -2284,7 +2281,7 @@ static void win_update(win_T *wp, DecorProviders *providers) spellvars_T zero_spv = { 0 }; row = win_line(wp, lnum, srow, wp->w_grid.rows, false, foldinfo.fi_lines > 0 ? &zero_spv : &spv, - foldinfo, &line_providers); + foldinfo); if (foldinfo.fi_lines == 0) { wp->w_lines[idx].wl_folded = false; @@ -2322,7 +2319,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // text doesn't need to be drawn, but the number column does. foldinfo_T info = wp->w_p_cul && lnum == wp->w_cursor.lnum ? cursorline_fi : fold_info(wp, lnum); - (void)win_line(wp, lnum, srow, wp->w_grid.rows, true, &spv, info, &line_providers); + (void)win_line(wp, lnum, srow, wp->w_grid.rows, true, &spv, info); } // This line does not need to be drawn, advance to the next one. @@ -2344,7 +2341,7 @@ static void win_update(win_T *wp, DecorProviders *providers) wp->w_lines_valid = 0; wp->w_valid &= ~VALID_WCOL; decor_redraw_reset(wp, &decor_state); - decor_providers_invoke_win(wp, providers, &line_providers); + decor_providers_invoke_win(wp); continue; } @@ -2419,7 +2416,7 @@ static void win_update(win_T *wp, DecorProviders *providers) spellvars_T zero_spv = { 0 }; foldinfo_T zero_foldinfo = { 0 }; row = win_line(wp, wp->w_botline, row, wp->w_grid.rows, false, &zero_spv, - zero_foldinfo, &line_providers); + zero_foldinfo); } } else if (dollar_vcol == -1) { wp->w_botline = lnum; @@ -2443,8 +2440,6 @@ static void win_update(win_T *wp, DecorProviders *providers) set_empty_rows(wp, row); } - kvi_destroy(line_providers); - if (wp->w_redr_type >= UPD_REDRAW_TOP) { draw_vsep_win(wp); draw_hsep_win(wp); @@ -2485,7 +2480,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // Don't update for changes in buffer again. int mod_set = curbuf->b_mod_set; curbuf->b_mod_set = false; - win_update(curwin, providers); + win_update(curwin); must_redraw = 0; curbuf->b_mod_set = mod_set; } -- cgit From e632396bab024ffefd1ed65bb4ac0203a9f491ce Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Fri, 22 Dec 2023 23:31:07 +0100 Subject: refactor(drawline): avoid storing info to draw 'statuscolumn' (#26712) We no longer return to the main loop in win_line() to put column characters on the screen. Simplify and sync statuscolumn drawing logic with that of statusline. --- src/nvim/drawline.c | 96 +++++++++++++++++----------------------------- src/nvim/statusline.c | 6 +-- src/nvim/statusline_defs.h | 11 +----- 3 files changed, 41 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index e34c22d907..e7b56dcd68 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -604,24 +604,24 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int } } -/// Prepare and build the 'statuscolumn' string for line "lnum" in window "wp". +/// Build and draw the 'statuscolumn' string for line "lnum" in window "wp". /// Fill "stcp" with the built status column string and attributes. -/// This can be called three times per win_line(), once for virt_lines, once for -/// the start of the buffer line "lnum" and once for the wrapped lines. /// /// @param[out] stcp Status column attributes -static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T *stcp) +static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int virtnum, + statuscol_T *stcp) { // When called for the first non-filler row of line "lnum" set num v:vars linenr_T relnum = virtnum == 0 ? abs(get_cursor_rel_lnum(wp, lnum)) : -1; + char buf[MAXPATHL]; // When a buffer's line count has changed, make a best estimate for the full // width of the status column by building with "w_nrwidth_line_count". Add // potentially truncated width and rebuild before drawing anything. if (wp->w_statuscol_line_count != wp->w_nrwidth_line_count) { wp->w_statuscol_line_count = wp->w_nrwidth_line_count; set_vim_var_nr(VV_VIRTNUM, 0); - build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, stcp); + build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, buf, stcp); if (stcp->truncate > 0) { // Add truncated width to avoid unnecessary redraws int addwidth = MIN(stcp->truncate, MAX_NUMBERWIDTH - wp->w_nrwidth); @@ -634,7 +634,7 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T } set_vim_var_nr(VV_VIRTNUM, virtnum); - int width = build_statuscol_str(wp, lnum, relnum, stcp); + int width = build_statuscol_str(wp, lnum, relnum, buf, stcp); // Force a redraw in case of error or when truncated if (*wp->w_p_stc == NUL || (stcp->truncate > 0 && wp->w_nrwidth < MAX_NUMBERWIDTH)) { if (stcp->truncate > 0) { // Avoid truncating 'statuscolumn' @@ -648,44 +648,26 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T return; } - // Reset text/highlight pointer and current attr for new line - stcp->textp = stcp->text; - stcp->hlrecp = stcp->hlrec; - stcp->cur_attr = stcp->num_attr; - stcp->text_end = stcp->text + strlen(stcp->text); - - int fill = stcp->width - width; - if (fill > 0) { - // Fill up with ' ' - memset(stcp->text_end, ' ', (size_t)fill); - *(stcp->text_end += fill) = NUL; + char *p = buf; + char transbuf[MAXPATHL]; + int attr = stcp->num_attr; + size_t len = strlen(buf); + + // Draw each segment with the specified highlighting. + for (stl_hlrec_t *sp = stcp->hlrec; sp->start != NULL; sp++) { + ptrdiff_t textlen = sp->start - p; + // Make all characters printable. + size_t translen = transstr_buf(p, textlen, transbuf, MAXPATHL, true); + draw_col_buf(wp, wlv, transbuf, translen, attr, false); + p = sp->start; + int hl = sp->userhl; + attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr; } -} + size_t translen = transstr_buf(p, buf + len - p, transbuf, MAXPATHL, true); + draw_col_buf(wp, wlv, transbuf, translen, attr, false); -/// Get information needed to display the next segment in the 'statuscolumn'. -/// -/// @param stcp Status column attributes -/// @param[in,out] wlv -static void draw_statuscol(win_T *wp, statuscol_T *stcp, winlinevars_T *wlv) -{ - do { - int attr = stcp->cur_attr; - char *start = stcp->textp; - stcp->textp = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end; - ptrdiff_t len = stcp->textp - start; - // Prepare for next highlight section if not yet at the end - if (stcp->textp < stcp->text_end) { - int hl = stcp->hlrecp->userhl; - stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr; - stcp->hlrecp++; - } - // Skip over empty highlight sections - if (len) { - static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * SIGN_WIDTH) * MB_MAXBYTES + 1]; - size_t translen = transstr_buf(start, len, transbuf, sizeof transbuf, true); - draw_col_buf(wp, wlv, transbuf, translen, attr, false); - } - } while (stcp->textp < stcp->text_end); + // Fill up with ' ' + draw_col_fill(wlv, ' ', stcp->width - width, stcp->num_attr); } static void handle_breakindent(win_T *wp, winlinevars_T *wlv) @@ -1550,19 +1532,16 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (sign_num_attr == 0) { statuscol.num_attr = get_line_number_attr(wp, &wlv); } - if (statuscol.textp == NULL) { - v = (ptr - line); - get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol); - if (!end_fill) { - // Get the line again as evaluating 'statuscolumn' may free it. - line = ml_get_buf(wp->w_buffer, lnum); - ptr = line + v; - } - if (wp->w_redr_statuscol) { - break; - } + v = (ptr - line); + draw_statuscol(wp, &wlv, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol); + if (wp->w_redr_statuscol) { + break; + } + if (!end_fill) { + // Get the line again as evaluating 'statuscolumn' may free it. + line = ml_get_buf(wp->w_buffer, lnum); + ptr = line + v; } - draw_statuscol(wp, &statuscol, &wlv); } else { // draw builtin info columns: fold, sign, number draw_foldcolumn(wp, &wlv); @@ -2906,12 +2885,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (wlv.filler_todo <= 0) { wlv.need_showbreak = true; } - if (statuscol.draw) { - if (vim_strchr(p_cpo, CPO_NUMCOL) && wlv.row > startrow + wlv.filler_lines) { - statuscol.draw = false; // don't draw status column if "n" is in 'cpo' - } else { - statuscol.textp = NULL; // re-evaluate with new v:virtnum - } + if (statuscol.draw && vim_strchr(p_cpo, CPO_NUMCOL) + && wlv.row > startrow + wlv.filler_lines) { + statuscol.draw = false; // don't draw status column if "n" is in 'cpo' } wlv.filler_todo--; virt_line_offset = -1; diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index e249317bd3..563e1d0a5b 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -867,7 +867,7 @@ void draw_tabline(void) /// the v:lnum and v:relnum variables don't have to be updated. /// /// @return The width of the built status column string for line "lnum" -int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T *stcp) +int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, statuscol_T *stcp) { // Only update click definitions once per window per redraw. // Don't update when current width is 0, since it will be redrawn again if not empty. @@ -880,7 +880,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * StlClickRecord *clickrec; char *stc = xstrdup(wp->w_p_stc); - int width = build_stl_str_hl(wp, stcp->text, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, ' ', + int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, ' ', stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp); xfree(stc); @@ -888,7 +888,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * stl_clear_click_defs(wp->w_statuscol_click_defs, wp->w_statuscol_click_defs_size); wp->w_statuscol_click_defs = stl_alloc_click_defs(wp->w_statuscol_click_defs, stcp->width, &wp->w_statuscol_click_defs_size); - stl_fill_click_defs(wp->w_statuscol_click_defs, clickrec, stcp->text, stcp->width, false); + stl_fill_click_defs(wp->w_statuscol_click_defs, clickrec, buf, stcp->width, false); } return width; diff --git a/src/nvim/statusline_defs.h b/src/nvim/statusline_defs.h index c1a54f4f54..e4b1c627ad 100644 --- a/src/nvim/statusline_defs.h +++ b/src/nvim/statusline_defs.h @@ -57,21 +57,14 @@ struct stl_item { }; /// Struct to hold info for 'statuscolumn' -typedef struct statuscol statuscol_T; - -struct statuscol { +typedef struct { int width; ///< width of the status column - int cur_attr; ///< current attributes in text int num_attr; ///< default highlight attr int sign_cul_id; ///< cursorline sign highlight id int truncate; ///< truncated width bool draw; ///< whether to draw the statuscolumn bool use_cul; ///< whether to use cursorline attrs - char text[MAXPATHL]; ///< text in status column - char *textp; ///< current position in text - char *text_end; ///< end of text (the NUL byte) stl_hlrec_t *hlrec; ///< highlight groups - stl_hlrec_t *hlrecp; ///< current highlight group foldinfo_T foldinfo; ///< fold information SignTextAttrs *sattrs; ///< sign attributes -}; +} statuscol_T; -- cgit From 242261d4e77806cdb4559c2be58613113a393a4e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 23 Dec 2023 08:28:17 +0800 Subject: refactor(IWYU): move evalarg_T to eval_defs.h (#26716) --- src/clint.py | 2 - src/nvim/decoration.c | 1 + src/nvim/drawline.c | 1 + src/nvim/drawscreen.c | 1 - src/nvim/eval.c | 89 +---------------------------------------- src/nvim/eval.h | 42 +++---------------- src/nvim/eval/typval_encode.c.h | 3 +- src/nvim/eval/userfunc.h | 2 +- src/nvim/eval/vars.c | 2 + src/nvim/eval_defs.h | 30 ++++++++++++++ src/nvim/ex_session.c | 46 +++++++++++++++++++++ src/nvim/move.c | 1 - src/nvim/shada.c | 42 +++++++++++++++++++ src/nvim/statusline_defs.h | 3 -- 14 files changed, 132 insertions(+), 133 deletions(-) create mode 100644 src/nvim/eval_defs.h (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 663416553e..32ed81f95c 100755 --- a/src/clint.py +++ b/src/clint.py @@ -903,11 +903,9 @@ def CheckIncludes(filename, lines, error): "src/nvim/buffer.h", "src/nvim/channel.h", "src/nvim/charset.h", - "src/nvim/eval.h", "src/nvim/eval/encode.h", "src/nvim/eval/typval.h", "src/nvim/eval/typval_defs.h", - "src/nvim/eval/userfunc.h", "src/nvim/event/libuv_process.h", "src/nvim/event/multiqueue.h", "src/nvim/garray.h", diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 6f1416711a..8766f2ca76 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "nvim/api/extmark.h" #include "nvim/api/private/helpers.h" diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index e7b56dcd68..77d554d759 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -36,6 +36,7 @@ #include "nvim/move.h" #include "nvim/option.h" #include "nvim/option_vars.h" +#include "nvim/os/os_defs.h" #include "nvim/plines.h" #include "nvim/pos_defs.h" #include "nvim/quickfix.h" diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 21e8438367..4200ff70bc 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -98,7 +98,6 @@ #include "nvim/profile.h" #include "nvim/regexp.h" #include "nvim/search.h" -#include "nvim/sign_defs.h" #include "nvim/spell.h" #include "nvim/state.h" #include "nvim/statusline.h" diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 3818944fc9..43aeda06ef 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -36,7 +36,6 @@ #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" -#include "nvim/ex_session.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" @@ -8160,7 +8159,7 @@ const char *find_option_var_end(const char **const arg, OptIndex *const opt_idxp return end; } -static var_flavour_T var_flavour(char *varname) +var_flavour_T var_flavour(char *varname) FUNC_ATTR_PURE { char *p = varname; @@ -8176,48 +8175,6 @@ static var_flavour_T var_flavour(char *varname) return VAR_FLAVOUR_DEFAULT; } -/// Iterate over global variables -/// -/// @warning No modifications to global variable dictionary must be performed -/// while iteration is in progress. -/// -/// @param[in] iter Iterator. Pass NULL to start iteration. -/// @param[out] name Variable name. -/// @param[out] rettv Variable value. -/// -/// @return Pointer that needs to be passed to next `var_shada_iter` invocation -/// or NULL to indicate that iteration is over. -const void *var_shada_iter(const void *const iter, const char **const name, typval_T *rettv, - var_flavour_T flavour) - FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3) -{ - const hashitem_T *hi; - const hashitem_T *hifirst = globvarht.ht_array; - const size_t hinum = (size_t)globvarht.ht_mask + 1; - *name = NULL; - if (iter == NULL) { - hi = globvarht.ht_array; - while ((size_t)(hi - hifirst) < hinum - && (HASHITEM_EMPTY(hi) - || !(var_flavour(hi->hi_key) & flavour))) { - hi++; - } - if ((size_t)(hi - hifirst) == hinum) { - return NULL; - } - } else { - hi = (const hashitem_T *)iter; - } - *name = TV_DICT_HI2DI(hi)->di_key; - tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv); - while ((size_t)(++hi - hifirst) < hinum) { - if (!HASHITEM_EMPTY(hi) && (var_flavour(hi->hi_key) & flavour)) { - return hi; - } - } - return NULL; -} - void var_set_global(const char *const name, typval_T vartv) { funccal_entry_T funccall_entry; @@ -8227,50 +8184,6 @@ void var_set_global(const char *const name, typval_T vartv) restore_funccal(); } -int store_session_globals(FILE *fd) -{ - TV_DICT_ITER(&globvardict, this_var, { - if ((this_var->di_tv.v_type == VAR_NUMBER - || this_var->di_tv.v_type == VAR_STRING) - && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { - // Escape special characters with a backslash. Turn a LF and - // CR into \n and \r. - char *const p = vim_strsave_escaped(tv_get_string(&this_var->di_tv), "\\\"\n\r"); - for (char *t = p; *t != NUL; t++) { - if (*t == '\n') { - *t = 'n'; - } else if (*t == '\r') { - *t = 'r'; - } - } - if ((fprintf(fd, "let %s = %c%s%c", - this_var->di_key, - ((this_var->di_tv.v_type == VAR_STRING) ? '"' : ' '), - p, - ((this_var->di_tv.v_type == VAR_STRING) ? '"' : ' ')) < 0) - || put_eol(fd) == FAIL) { - xfree(p); - return FAIL; - } - xfree(p); - } else if (this_var->di_tv.v_type == VAR_FLOAT - && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { - float_T f = this_var->di_tv.vval.v_float; - int sign = ' '; - - if (f < 0) { - f = -f; - sign = '-'; - } - if ((fprintf(fd, "let %s = %c%f", this_var->di_key, sign, f) < 0) - || put_eol(fd) == FAIL) { - return FAIL; - } - } - }); - return OK; -} - /// Display script name where an item was last set. /// Should only be invoked when 'verbose' is non-zero. void last_set_msg(sctx_T script_ctx) diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 9ee5d99806..951a6313b6 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -7,8 +7,9 @@ #include "nvim/channel_defs.h" // IWYU pragma: keep #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" -#include "nvim/event/time.h" -#include "nvim/ex_cmds_defs.h" +#include "nvim/eval_defs.h" // IWYU pragma: export +#include "nvim/event/defs.h" +#include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/grid_defs.h" // IWYU pragma: keep #include "nvim/hashtab_defs.h" #include "nvim/macros_defs.h" @@ -177,24 +178,8 @@ typedef enum { VV_VIRTNUM, } VimVarIndex; -/// All recognized msgpack types -typedef enum { - kMPNil, - kMPBoolean, - kMPInteger, - kMPFloat, - kMPString, - kMPBinary, - kMPArray, - kMPMap, - kMPExt, -} MessagePackType; -#define LAST_MSGPACK_TYPE kMPExt - /// Array mapping values from MessagePackType to corresponding list pointers -extern const list_T *eval_msgpack_type_lists[LAST_MSGPACK_TYPE + 1]; - -#undef LAST_MSGPACK_TYPE +extern const list_T *eval_msgpack_type_lists[NUM_MSGPACK_TYPES]; // Struct passed to get_v_event() and restore_v_event(). typedef struct { @@ -258,32 +243,17 @@ typedef enum { kDictListItems, ///< List dictionary contents: [keys, values]. } DictListType; -typedef int (*ex_unletlock_callback)(lval_T *, char *, exarg_T *, int); - // Used for checking if local variables or arguments used in a lambda. extern bool *eval_lavars_used; -/// Struct passed through eval() functions. -/// See EVALARG_EVALUATE for a fixed value with eval_flags set to EVAL_EVALUATE. -typedef struct { - int eval_flags; ///< EVAL_ flag values below - - /// copied from exarg_T when "getline" is "getsourceline". Can be NULL. - LineGetter eval_getline; - void *eval_cookie; ///< argument for eval_getline() - - /// pointer to the last line obtained with getsourceline() - char *eval_tofree; -} evalarg_T; +// Character used as separated in autoload function/variable names. +#define AUTOLOAD_CHAR '#' /// Flag for expression evaluation. enum { EVAL_EVALUATE = 1, ///< when missing don't actually evaluate }; -// Character used as separated in autoload function/variable names. -#define AUTOLOAD_CHAR '#' - /// Passed to an eval() function to enable evaluation. EXTERN evalarg_T EVALARG_EVALUATE INIT( = { EVAL_EVALUATE, NULL, NULL, NULL }); diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index 2e0b68d486..c0cd0ce557 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -246,11 +246,12 @@ #include #include +#include "klib/kvec.h" +#include "nvim/eval.h" #include "nvim/eval/encode.h" #include "nvim/eval/typval.h" #include "nvim/eval/typval_encode.h" #include "nvim/func_attr.h" -#include "klib/kvec.h" /// Dummy variable used because some macros need lvalue /// diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 270ca7db4e..b3488b15a7 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -4,8 +4,8 @@ #include #include "nvim/cmdexpand_defs.h" // IWYU pragma: keep -#include "nvim/eval.h" // IWYU pragma: keep #include "nvim/eval/typval_defs.h" +#include "nvim/eval_defs.h" // IWYU pragma: keep #include "nvim/ex_cmds_defs.h" // IWYU pragma: keep #include "nvim/hashtab_defs.h" // IWYU pragma: keep #include "nvim/pos_defs.h" diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 8ed76341b0..dd984e8819 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -43,6 +43,8 @@ #include "nvim/vim_defs.h" #include "nvim/window.h" +typedef int (*ex_unletlock_callback)(lval_T *, char *, exarg_T *, int); + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval/vars.c.generated.h" #endif diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h new file mode 100644 index 0000000000..4bbebb14f5 --- /dev/null +++ b/src/nvim/eval_defs.h @@ -0,0 +1,30 @@ +#pragma once + +#include "nvim/ex_cmds_defs.h" + +/// All recognized msgpack types +typedef enum { + kMPNil, + kMPBoolean, + kMPInteger, + kMPFloat, + kMPString, + kMPBinary, + kMPArray, + kMPMap, + kMPExt, +} MessagePackType; +#define NUM_MSGPACK_TYPES (kMPExt + 1) + +/// Struct passed through eval() functions. +/// See EVALARG_EVALUATE for a fixed value with eval_flags set to EVAL_EVALUATE. +typedef struct { + int eval_flags; ///< EVAL_ flag values below + + /// copied from exarg_T when "getline" is "getsourceline". Can be NULL. + LineGetter eval_getline; + void *eval_cookie; ///< argument for eval_getline() + + /// pointer to the last line obtained with getsourceline() + char *eval_tofree; +} evalarg_T; diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 82e3fe09d2..98869c0a25 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -13,6 +13,7 @@ #include "nvim/ascii_defs.h" #include "nvim/buffer.h" #include "nvim/eval.h" +#include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" @@ -35,6 +36,7 @@ #include "nvim/path.h" #include "nvim/pos_defs.h" #include "nvim/runtime.h" +#include "nvim/strings.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" #include "nvim/window.h" @@ -519,6 +521,50 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr return OK; } +static int store_session_globals(FILE *fd) +{ + TV_DICT_ITER(&globvardict, this_var, { + if ((this_var->di_tv.v_type == VAR_NUMBER + || this_var->di_tv.v_type == VAR_STRING) + && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { + // Escape special characters with a backslash. Turn a LF and + // CR into \n and \r. + char *const p = vim_strsave_escaped(tv_get_string(&this_var->di_tv), "\\\"\n\r"); + for (char *t = p; *t != NUL; t++) { + if (*t == '\n') { + *t = 'n'; + } else if (*t == '\r') { + *t = 'r'; + } + } + if ((fprintf(fd, "let %s = %c%s%c", + this_var->di_key, + ((this_var->di_tv.v_type == VAR_STRING) ? '"' : ' '), + p, + ((this_var->di_tv.v_type == VAR_STRING) ? '"' : ' ')) < 0) + || put_eol(fd) == FAIL) { + xfree(p); + return FAIL; + } + xfree(p); + } else if (this_var->di_tv.v_type == VAR_FLOAT + && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) { + float_T f = this_var->di_tv.vval.v_float; + int sign = ' '; + + if (f < 0) { + f = -f; + sign = '-'; + } + if ((fprintf(fd, "let %s = %c%f", this_var->di_key, sign, f) < 0) + || put_eol(fd) == FAIL) { + return FAIL; + } + } + }); + return OK; +} + /// Writes commands for restoring the current buffers, for :mksession. /// /// Legacy 'sessionoptions'/'viewoptions' flags SSOP_UNIX, SSOP_SLASH are diff --git a/src/nvim/move.c b/src/nvim/move.c index c4f8eca493..d7bd18f23b 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -40,7 +40,6 @@ #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" #include "nvim/search.h" -#include "nvim/sign_defs.h" #include "nvim/strings.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 09142e55e0..efef6f8511 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -996,6 +996,48 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p) #define HMS_ITER(hms_p, cur_entry, code) \ HMLL_FORALL(&((hms_p)->hmll), cur_entry, code) +/// Iterate over global variables +/// +/// @warning No modifications to global variable dictionary must be performed +/// while iteration is in progress. +/// +/// @param[in] iter Iterator. Pass NULL to start iteration. +/// @param[out] name Variable name. +/// @param[out] rettv Variable value. +/// +/// @return Pointer that needs to be passed to next `var_shada_iter` invocation +/// or NULL to indicate that iteration is over. +static const void *var_shada_iter(const void *const iter, const char **const name, typval_T *rettv, + var_flavour_T flavour) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3) +{ + const hashitem_T *hi; + const hashitem_T *hifirst = globvarht.ht_array; + const size_t hinum = (size_t)globvarht.ht_mask + 1; + *name = NULL; + if (iter == NULL) { + hi = globvarht.ht_array; + while ((size_t)(hi - hifirst) < hinum + && (HASHITEM_EMPTY(hi) + || !(var_flavour(hi->hi_key) & flavour))) { + hi++; + } + if ((size_t)(hi - hifirst) == hinum) { + return NULL; + } + } else { + hi = (const hashitem_T *)iter; + } + *name = TV_DICT_HI2DI(hi)->di_key; + tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv); + while ((size_t)(++hi - hifirst) < hinum) { + if (!HASHITEM_EMPTY(hi) && (var_flavour(hi->hi_key) & flavour)) { + return hi; + } + } + return NULL; +} + /// Find buffer for given buffer name (cached) /// /// @param[in,out] fname_bufs Cache containing fname to buffer mapping. diff --git a/src/nvim/statusline_defs.h b/src/nvim/statusline_defs.h index e4b1c627ad..a8588b54d7 100644 --- a/src/nvim/statusline_defs.h +++ b/src/nvim/statusline_defs.h @@ -1,11 +1,8 @@ #pragma once #include -#include #include "nvim/fold_defs.h" -#include "nvim/macros_defs.h" -#include "nvim/os/os_defs.h" #include "nvim/sign_defs.h" /// Status line click definition -- cgit From 1d2af15a956458f09b526d23f1d0135da9b90bb4 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Mon, 18 Dec 2023 04:02:07 +0600 Subject: refactor(options): restructure functions related to key options --- src/nvim/option.c | 55 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 4969ac7f1d..0704dac5b2 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1495,12 +1495,36 @@ int do_set(char *arg, int opt_flags) return OK; } +// Translate a string like "t_xx", "" or "" to a key number. +// When "has_lt" is true there is a '<' before "*arg_arg". +// Returns 0 when the key is not recognized. +static int find_key_len(const char *arg_arg, size_t len, bool has_lt) +{ + int key = 0; + const char *arg = arg_arg; + + // Don't use get_special_key_code() for t_xx, we don't want it to call + // add_termcap_entry(). + if (len >= 4 && arg[0] == 't' && arg[1] == '_') { + key = TERMCAP2KEY((uint8_t)arg[2], (uint8_t)arg[3]); + } else if (has_lt) { + arg--; // put arg at the '<' + int modifiers = 0; + key = find_special_key(&arg, len + 1, &modifiers, FSK_KEYCODE | FSK_KEEP_X_KEY | FSK_SIMPLIFY, + NULL); + if (modifiers) { // can't handle modifiers here + key = 0; + } + } + return key; +} + /// Convert a key name or string into a key value. /// Used for 'wildchar' and 'cedit' options. int string_to_key(char *arg) { if (*arg == '<') { - return find_key_option(arg + 1, true); + return find_key_len(arg + 1, strlen(arg), true); } if (*arg == '^') { return CTRL_CHR((uint8_t)arg[1]); @@ -3762,35 +3786,6 @@ void set_option_value_give_err(const OptIndex opt_idx, OptVal value, int opt_fla } } -// Translate a string like "t_xx", "" or "" to a key number. -// When "has_lt" is true there is a '<' before "*arg_arg". -// Returns 0 when the key is not recognized. -int find_key_option_len(const char *arg_arg, size_t len, bool has_lt) -{ - int key = 0; - const char *arg = arg_arg; - - // Don't use get_special_key_code() for t_xx, we don't want it to call - // add_termcap_entry(). - if (len >= 4 && arg[0] == 't' && arg[1] == '_') { - key = TERMCAP2KEY((uint8_t)arg[2], (uint8_t)arg[3]); - } else if (has_lt) { - arg--; // put arg at the '<' - int modifiers = 0; - key = find_special_key(&arg, len + 1, &modifiers, - FSK_KEYCODE | FSK_KEEP_X_KEY | FSK_SIMPLIFY, NULL); - if (modifiers) { // can't handle modifiers here - key = 0; - } - } - return key; -} - -static int find_key_option(const char *arg, bool has_lt) -{ - return find_key_option_len(arg, strlen(arg), has_lt); -} - /// if 'all' == false: show changed options /// if 'all' == true: show all normal options /// -- cgit From 4d98ec2fa45a100292c490acc606dfb55a0573c1 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Mon, 18 Dec 2023 04:10:41 +0600 Subject: refactor(options): move some functions from options.c to option.c --- src/nvim/api/options.c | 235 ------------------------------------------------ src/nvim/option.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++- src/nvim/optionstr.c | 2 +- 3 files changed, 238 insertions(+), 238 deletions(-) (limited to 'src') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index fb461152b4..ff1741558d 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -10,7 +10,6 @@ #include "nvim/api/private/validate.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" -#include "nvim/eval/window.h" #include "nvim/globals.h" #include "nvim/macros_defs.h" #include "nvim/memory.h" @@ -320,237 +319,3 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) return get_vimoption(name, scope, buf, win, err); } - -/// Switch current context to get/set option value for window/buffer. -/// -/// @param[out] ctx Current context. switchwin_T for window and aco_save_T for buffer. -/// @param req_scope Requested option scope. See OptReqScope in option.h. -/// @param[in] from Target buffer/window. -/// @param[out] err Error message, if any. -/// -/// @return true if context was switched, false otherwise. -static bool switch_option_context(void *const ctx, OptReqScope req_scope, void *const from, - Error *err) -{ - switch (req_scope) { - case kOptReqWin: { - win_T *const win = (win_T *)from; - switchwin_T *const switchwin = (switchwin_T *)ctx; - - if (win == curwin) { - return false; - } - - if (switch_win_noblock(switchwin, win, win_find_tabpage(win), true) - == FAIL) { - restore_win_noblock(switchwin, true); - - if (try_end(err)) { - return false; - } - api_set_error(err, kErrorTypeException, "Problem while switching windows"); - return false; - } - return true; - } - case kOptReqBuf: { - buf_T *const buf = (buf_T *)from; - aco_save_T *const aco = (aco_save_T *)ctx; - - if (buf == curbuf) { - return false; - } - aucmd_prepbuf(aco, buf); - return true; - } - case kOptReqGlobal: - return false; - } - UNREACHABLE; -} - -/// Restore context after getting/setting option for window/buffer. See switch_option_context() for -/// params. -static void restore_option_context(void *const ctx, OptReqScope req_scope) -{ - switch (req_scope) { - case kOptReqWin: - restore_win_noblock((switchwin_T *)ctx, true); - break; - case kOptReqBuf: - aucmd_restbuf((aco_save_T *)ctx); - break; - case kOptReqGlobal: - break; - } -} - -/// Get attributes for an option. -/// -/// @param opt_idx Option index in options[] table. -/// -/// @return Option attributes. -/// 0 for hidden or unknown option. -/// See SOPT_* in option_defs.h for other flags. -int get_option_attrs(OptIndex opt_idx) -{ - if (opt_idx == kOptInvalid) { - return 0; - } - - vimoption_T *opt = get_option(opt_idx); - - // Hidden option - if (opt->var == NULL) { - return 0; - } - - int attrs = 0; - - if (opt->indir == PV_NONE || (opt->indir & PV_BOTH)) { - attrs |= SOPT_GLOBAL; - } - if (opt->indir & PV_WIN) { - attrs |= SOPT_WIN; - } else if (opt->indir & PV_BUF) { - attrs |= SOPT_BUF; - } - - return attrs; -} - -/// Check if option has a value in the requested scope. -/// -/// @param opt_idx Option index in options[] table. -/// @param req_scope Requested option scope. See OptReqScope in option.h. -/// -/// @return true if option has a value in the requested scope, false otherwise. -static bool option_has_scope(OptIndex opt_idx, OptReqScope req_scope) -{ - if (opt_idx == kOptInvalid) { - return false; - } - - vimoption_T *opt = get_option(opt_idx); - - // Hidden option. - if (opt->var == NULL) { - return false; - } - // TTY option. - if (is_tty_option(opt->fullname)) { - return req_scope == kOptReqGlobal; - } - - switch (req_scope) { - case kOptReqGlobal: - return opt->var != VAR_WIN; - case kOptReqBuf: - return opt->indir & PV_BUF; - case kOptReqWin: - return opt->indir & PV_WIN; - } - UNREACHABLE; -} - -/// Get the option value in the requested scope. -/// -/// @param opt_idx Option index in options[] table. -/// @param req_scope Requested option scope. See OptReqScope in option.h. -/// @param[in] from Pointer to buffer or window for local option value. -/// @param[out] err Error message, if any. -/// -/// @return Option value in the requested scope. Returns a Nil option value if option is not found, -/// hidden or if it isn't present in the requested scope. (i.e. has no global, window-local or -/// buffer-local value depending on opt_scope). -OptVal get_option_value_strict(OptIndex opt_idx, OptReqScope req_scope, void *from, Error *err) -{ - if (opt_idx == kOptInvalid || !option_has_scope(opt_idx, req_scope)) { - return NIL_OPTVAL; - } - - vimoption_T *opt = get_option(opt_idx); - switchwin_T switchwin; - aco_save_T aco; - void *ctx = req_scope == kOptReqWin ? (void *)&switchwin - : (req_scope == kOptReqBuf ? (void *)&aco : NULL); - bool switched = switch_option_context(ctx, req_scope, from, err); - if (ERROR_SET(err)) { - return NIL_OPTVAL; - } - - char *varp = get_varp_scope(opt, req_scope == kOptReqGlobal ? OPT_GLOBAL : OPT_LOCAL); - OptVal retv = optval_from_varp(opt_idx, varp); - - if (switched) { - restore_option_context(ctx, req_scope); - } - - return retv; -} - -/// Get option value for buffer / window. -/// -/// @param opt_idx Option index in options[] table. -/// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). -/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). -/// @param[out] hidden Whether option is hidden. -/// @param req_scope Requested option scope. See OptReqScope in option.h. -/// @param[in] from Target buffer/window. -/// @param[out] err Error message, if any. -/// -/// @return Option value. Must be freed by caller. -OptVal get_option_value_for(OptIndex opt_idx, int scope, const OptReqScope req_scope, - void *const from, Error *err) -{ - switchwin_T switchwin; - aco_save_T aco; - void *ctx = req_scope == kOptReqWin ? (void *)&switchwin - : (req_scope == kOptReqBuf ? (void *)&aco : NULL); - - bool switched = switch_option_context(ctx, req_scope, from, err); - if (ERROR_SET(err)) { - return NIL_OPTVAL; - } - - OptVal retv = get_option_value(opt_idx, scope); - - if (switched) { - restore_option_context(ctx, req_scope); - } - - return retv; -} - -/// Set option value for buffer / window. -/// -/// @param name Option name. -/// @param opt_idx Option index in options[] table. -/// @param[in] value Option value. -/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). -/// @param req_scope Requested option scope. See OptReqScope in option.h. -/// @param[in] from Target buffer/window. -/// @param[out] err Error message, if any. -void set_option_value_for(const char *name, OptIndex opt_idx, OptVal value, const int opt_flags, - const OptReqScope req_scope, void *const from, Error *err) - FUNC_ATTR_NONNULL_ARG(1) -{ - switchwin_T switchwin; - aco_save_T aco; - void *ctx = req_scope == kOptReqWin ? (void *)&switchwin - : (req_scope == kOptReqBuf ? (void *)&aco : NULL); - - bool switched = switch_option_context(ctx, req_scope, from, err); - if (ERROR_SET(err)) { - return; - } - - const char *const errmsg = set_option_value_handle_tty(name, opt_idx, value, opt_flags); - if (errmsg) { - api_set_error(err, kErrorTypeException, "%s", errmsg); - } - - if (switched) { - restore_option_context(ctx, req_scope); - } -} diff --git a/src/nvim/option.c b/src/nvim/option.c index 0704dac5b2..f082bd83a7 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -44,6 +44,7 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/vars.h" +#include "nvim/eval/window.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" @@ -3747,7 +3748,7 @@ const char *set_option_value(const OptIndex opt_idx, const OptVal value, int opt /// Set the value of an option. Supports TTY options, unlike set_option_value(). /// /// @param name Option name. Used for error messages and for setting TTY options. -/// @param opt_idx Option indx in options[] table. If less than zero, `name` is used to +/// @param opt_idx Option indx in options[] table. If kOptInvalid, `name` is used to /// check if the option is a TTY option, and an error is shown if it's not. /// If the option is a TTY option, the function fails silently. /// @param value Option value. If NIL_OPTVAL, the option value is cleared. @@ -3786,6 +3787,240 @@ void set_option_value_give_err(const OptIndex opt_idx, OptVal value, int opt_fla } } +/// Switch current context to get/set option value for window/buffer. +/// +/// @param[out] ctx Current context. switchwin_T for window and aco_save_T for buffer. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. +/// +/// @return true if context was switched, false otherwise. +static bool switch_option_context(void *const ctx, OptReqScope req_scope, void *const from, + Error *err) +{ + switch (req_scope) { + case kOptReqWin: { + win_T *const win = (win_T *)from; + switchwin_T *const switchwin = (switchwin_T *)ctx; + + if (win == curwin) { + return false; + } + + if (switch_win_noblock(switchwin, win, win_find_tabpage(win), true) + == FAIL) { + restore_win_noblock(switchwin, true); + + if (try_end(err)) { + return false; + } + api_set_error(err, kErrorTypeException, "Problem while switching windows"); + return false; + } + return true; + } + case kOptReqBuf: { + buf_T *const buf = (buf_T *)from; + aco_save_T *const aco = (aco_save_T *)ctx; + + if (buf == curbuf) { + return false; + } + aucmd_prepbuf(aco, buf); + return true; + } + case kOptReqGlobal: + return false; + } + UNREACHABLE; +} + +/// Restore context after getting/setting option for window/buffer. See switch_option_context() for +/// params. +static void restore_option_context(void *const ctx, OptReqScope req_scope) +{ + switch (req_scope) { + case kOptReqWin: + restore_win_noblock((switchwin_T *)ctx, true); + break; + case kOptReqBuf: + aucmd_restbuf((aco_save_T *)ctx); + break; + case kOptReqGlobal: + break; + } +} + +/// Get attributes for an option. +/// +/// @param opt_idx Option index in options[] table. +/// +/// @return Option attributes. +/// 0 for hidden or unknown option. +/// See SOPT_* in option_defs.h for other flags. +int get_option_attrs(OptIndex opt_idx) +{ + if (opt_idx == kOptInvalid) { + return 0; + } + + vimoption_T *opt = get_option(opt_idx); + + // Hidden option + if (opt->var == NULL) { + return 0; + } + + int attrs = 0; + + if (opt->indir == PV_NONE || (opt->indir & PV_BOTH)) { + attrs |= SOPT_GLOBAL; + } + if (opt->indir & PV_WIN) { + attrs |= SOPT_WIN; + } else if (opt->indir & PV_BUF) { + attrs |= SOPT_BUF; + } + + return attrs; +} + +/// Check if option has a value in the requested scope. +/// +/// @param opt_idx Option index in options[] table. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// +/// @return true if option has a value in the requested scope, false otherwise. +static bool option_has_scope(OptIndex opt_idx, OptReqScope req_scope) +{ + if (opt_idx == kOptInvalid) { + return false; + } + + vimoption_T *opt = get_option(opt_idx); + + // Hidden option. + if (opt->var == NULL) { + return false; + } + // TTY option. + if (is_tty_option(opt->fullname)) { + return req_scope == kOptReqGlobal; + } + + switch (req_scope) { + case kOptReqGlobal: + return opt->var != VAR_WIN; + case kOptReqBuf: + return opt->indir & PV_BUF; + case kOptReqWin: + return opt->indir & PV_WIN; + } + UNREACHABLE; +} + +/// Get the option value in the requested scope. +/// +/// @param opt_idx Option index in options[] table. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Pointer to buffer or window for local option value. +/// @param[out] err Error message, if any. +/// +/// @return Option value in the requested scope. Returns a Nil option value if option is not found, +/// hidden or if it isn't present in the requested scope. (i.e. has no global, window-local or +/// buffer-local value depending on opt_scope). +OptVal get_option_value_strict(OptIndex opt_idx, OptReqScope req_scope, void *from, Error *err) +{ + if (opt_idx == kOptInvalid || !option_has_scope(opt_idx, req_scope)) { + return NIL_OPTVAL; + } + + vimoption_T *opt = get_option(opt_idx); + switchwin_T switchwin; + aco_save_T aco; + void *ctx = req_scope == kOptReqWin ? (void *)&switchwin + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); + bool switched = switch_option_context(ctx, req_scope, from, err); + if (ERROR_SET(err)) { + return NIL_OPTVAL; + } + + char *varp = get_varp_scope(opt, req_scope == kOptReqGlobal ? OPT_GLOBAL : OPT_LOCAL); + OptVal retv = optval_from_varp(opt_idx, varp); + + if (switched) { + restore_option_context(ctx, req_scope); + } + + return retv; +} + +/// Get option value for buffer / window. +/// +/// @param opt_idx Option index in options[] table. +/// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). +/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). +/// @param[out] hidden Whether option is hidden. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. +/// +/// @return Option value. Must be freed by caller. +OptVal get_option_value_for(OptIndex opt_idx, int scope, const OptReqScope req_scope, + void *const from, Error *err) +{ + switchwin_T switchwin; + aco_save_T aco; + void *ctx = req_scope == kOptReqWin ? (void *)&switchwin + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); + + bool switched = switch_option_context(ctx, req_scope, from, err); + if (ERROR_SET(err)) { + return NIL_OPTVAL; + } + + OptVal retv = get_option_value(opt_idx, scope); + + if (switched) { + restore_option_context(ctx, req_scope); + } + + return retv; +} + +/// Set option value for buffer / window. +/// +/// @param name Option name. +/// @param opt_idx Option index in options[] table. +/// @param[in] value Option value. +/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. +void set_option_value_for(const char *name, OptIndex opt_idx, OptVal value, const int opt_flags, + const OptReqScope req_scope, void *const from, Error *err) + FUNC_ATTR_NONNULL_ARG(1) +{ + switchwin_T switchwin; + aco_save_T aco; + void *ctx = req_scope == kOptReqWin ? (void *)&switchwin + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); + + bool switched = switch_option_context(ctx, req_scope, from, err); + if (ERROR_SET(err)) { + return; + } + + const char *const errmsg = set_option_value_handle_tty(name, opt_idx, value, opt_flags); + if (errmsg) { + api_set_error(err, kErrorTypeException, "%s", errmsg); + } + + if (switched) { + restore_option_context(ctx, req_scope); + } +} + /// if 'all' == false: show changed options /// if 'all' == true: show all normal options /// @@ -6035,7 +6270,7 @@ dict_T *get_winbuf_options(const int bufopt) dict_T *const d = tv_dict_alloc(); for (OptIndex opt_idx = 0; opt_idx < kOptIndexCount; opt_idx++) { - struct vimoption *opt = &options[opt_idx]; + vimoption_T *opt = &options[opt_idx]; if ((bufopt && (opt->indir & PV_BUF)) || (!bufopt && (opt->indir & PV_WIN))) { diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 41facb86eb..6886be3c25 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -291,7 +291,7 @@ static void set_string_option_global(vimoption_T *opt, char **varp) /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL. /// /// TODO(famiu): Remove this and its win/buf variants. -void set_string_option_direct(OptIndex opt_idx, const char *val, int opt_flags, int set_sid) +void set_string_option_direct(OptIndex opt_idx, const char *val, int opt_flags, scid_T set_sid) { vimoption_T *opt = get_option(opt_idx); -- cgit From 8f72987837ce15156704f54951224de4ae36741d Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 22 Dec 2023 12:24:20 +0600 Subject: refactor(options): use `OptIndex` for `os_idx` --- src/nvim/option_defs.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 72fb5a92fc..c1b9b8d196 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -8,6 +8,10 @@ #include "nvim/regexp_defs.h" #include "nvim/types_defs.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "options_enum.generated.h" +#endif + /// Option value type. /// These types are also used as type flags by using the type value as an index for the type_flags /// bit field (@see option_has_type()). @@ -50,10 +54,11 @@ typedef struct { /// Pointer to the option variable. The variable can be an OptInt (numeric /// option), an int (boolean option) or a char pointer (string option). void *os_varp; - int os_idx; + OptIndex os_idx; int os_flags; /// Old value of the option. + /// TODO(famiu): Convert `os_oldval` and `os_newval` to `OptVal` to accomodate multitype options. OptValData os_oldval; /// New value of the option. OptValData os_newval; @@ -129,7 +134,3 @@ typedef enum { kOptReqWin = 1, ///< Request window-local option value kOptReqBuf = 2, ///< Request buffer-local option value } OptReqScope; - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "options_enum.generated.h" -#endif -- cgit From 3c667d3e0fe41a900cee9477e190ae02d7ec0c23 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 23 Dec 2023 15:30:44 +0800 Subject: fix(mappings): fix mapset() not replacing map with backslash (#26719) --- src/nvim/mapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index cb50050344..c7fa585a27 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -2350,7 +2350,7 @@ void f_mapset(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) // Delete any existing mapping for this lhs and mode. MapArguments unmap_args = MAP_ARGUMENTS_INIT; - set_maparg_lhs_rhs(lhs, strlen(lhs), "", 0, LUA_NOREF, 0, &unmap_args); + set_maparg_lhs_rhs(lhs, strlen(lhs), "", 0, LUA_NOREF, CPO_TO_CPO_FLAGS, &unmap_args); unmap_args.buffer = buffer; buf_do_map(MAPTYPE_UNMAP, &unmap_args, mode, is_abbr, curbuf); xfree(unmap_args.rhs); -- cgit From c16d5729b52d2f878cd035341b951b1f185b45c9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 23 Dec 2023 15:53:28 +0800 Subject: refactor: remove CPO_TO_CPO_FLAGS() (#26718) Just pass p_cpo to replace_termcodes() directly. This allows removing option_vars.h from keycodes.h, and also avoids the mistake of passing 0 as cpo_flags. --- src/clint.py | 1 - src/nvim/api/vim.c | 2 +- src/nvim/drawline.h | 1 - src/nvim/keycodes.c | 13 +++++++------ src/nvim/keycodes.h | 6 ------ src/nvim/mapping.c | 44 ++++++++++++++++++++++---------------------- src/nvim/menu.c | 2 +- src/nvim/usercmd.c | 2 +- 8 files changed, 32 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/clint.py b/src/clint.py index 32ed81f95c..2659abbb0e 100755 --- a/src/clint.py +++ b/src/clint.py @@ -912,7 +912,6 @@ def CheckIncludes(filename, lines, error): "src/nvim/globals.h", "src/nvim/grid.h", "src/nvim/highlight.h", - "src/nvim/keycodes.h", "src/nvim/lua/executor.h", "src/nvim/main.h", "src/nvim/mark.h", diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index aed286165a..860cca582c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -461,7 +461,7 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool } char *ptr = NULL; - replace_termcodes(str.data, str.size, &ptr, 0, flags, NULL, CPO_TO_CPO_FLAGS); + replace_termcodes(str.data, str.size, &ptr, 0, flags, NULL, p_cpo); return cstr_as_string(ptr); } diff --git a/src/nvim/drawline.h b/src/nvim/drawline.h index 97a6ca2eee..9112deddb3 100644 --- a/src/nvim/drawline.h +++ b/src/nvim/drawline.h @@ -4,7 +4,6 @@ #include #include "klib/kvec.h" -#include "nvim/decoration_defs.h" // IWYU pragma: keep #include "nvim/fold_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" #include "nvim/pos_defs.h" diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index 301c3846e7..d913beeb0c 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -852,8 +852,8 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) /// K_SPECIAL by itself is replaced by K_SPECIAL KS_SPECIAL KE_FILLER. /// /// When "flags" has REPTERM_FROM_PART, trailing is included, otherwise it is removed (to make -/// ":map xx ^V" map xx to nothing). When cpo_flags contains FLAG_CPO_BSLASH, a backslash can be -/// used in place of . All other characters are removed. +/// ":map xx ^V" map xx to nothing). When cpo_val contains CPO_BSLASH, a backslash can be used in +/// place of . All other characters are removed. /// /// @param[in] from What characters to replace. /// @param[in] from_len Length of the "from" argument. @@ -867,20 +867,21 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag) /// REPTERM_NO_SPECIAL do not accept notation /// REPTERM_NO_SIMPLIFY do not simplify into 0x08, etc. /// @param[out] did_simplify set when some code was simplified, unless it is NULL. -/// @param[in] cpo_flags Relevant flags derived from p_cpo, see CPO_TO_CPO_FLAGS. +/// @param[in] cpo_val The value of 'cpoptions' to use. Only CPO_BSLASH matters. /// /// @return The same as what `*bufp` is set to. char *replace_termcodes(const char *const from, const size_t from_len, char **const bufp, const scid_T sid_arg, const int flags, bool *const did_simplify, - const int cpo_flags) - FUNC_ATTR_NONNULL_ARG(1, 3) + const char *const cpo_val) + FUNC_ATTR_NONNULL_ARG(1, 3, 7) { char key; size_t dlen = 0; const char *src; const char *const end = from + from_len - 1; - const bool do_backslash = !(cpo_flags & FLAG_CPO_BSLASH); // backslash is a special character + // backslash is a special character + const bool do_backslash = (vim_strchr(cpo_val, CPO_BSLASH) == NULL); const bool do_special = !(flags & REPTERM_NO_SPECIAL); bool allocated = (*bufp == NULL); diff --git a/src/nvim/keycodes.h b/src/nvim/keycodes.h index fafe205f4d..6aebad5b66 100644 --- a/src/nvim/keycodes.h +++ b/src/nvim/keycodes.h @@ -4,7 +4,6 @@ #include "nvim/ascii_defs.h" #include "nvim/eval/typval_defs.h" // IWYU pragma: keep -#include "nvim/option_vars.h" // Keycode definitions for special keys. // @@ -475,11 +474,6 @@ enum key_extra { /// This is a total of 6 tokens, and is currently the longest one possible. #define MAX_KEY_CODE_LEN 6 -#define FLAG_CPO_BSLASH 0x01 -#define CPO_TO_CPO_FLAGS ((vim_strchr((char *)p_cpo, CPO_BSLASH) == NULL) \ - ? 0 \ - : FLAG_CPO_BSLASH) - /// Flags for replace_termcodes() enum { REPTERM_FROM_PART = 1, diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index c7fa585a27..63604352cf 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -303,11 +303,11 @@ static void showmap(mapblock_T *mp, bool local) /// @param[in] orig_rhs Original mapping RHS, with characters to replace. /// @param[in] rhs_lua Lua reference for Lua mappings. /// @param[in] orig_rhs_len `strlen` of orig_rhs. -/// @param[in] cpo_flags See param docs for @ref replace_termcodes. +/// @param[in] cpo_val See param docs for @ref replace_termcodes. /// @param[out] mapargs MapArguments struct holding the replaced strings. static bool set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs_len, const char *const orig_rhs, const size_t orig_rhs_len, - const LuaRef rhs_lua, const int cpo_flags, + const LuaRef rhs_lua, const char *const cpo_val, MapArguments *const mapargs) { char lhs_buf[128]; @@ -324,7 +324,7 @@ static bool set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs const int flags = REPTERM_FROM_PART | REPTERM_DO_LT; char *bufarg = lhs_buf; char *replaced = replace_termcodes(orig_lhs, orig_lhs_len, &bufarg, 0, - flags, &did_simplify, cpo_flags); + flags, &did_simplify, cpo_val); if (replaced == NULL) { return false; } @@ -332,7 +332,7 @@ static bool set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs xstrlcpy(mapargs->lhs, replaced, sizeof(mapargs->lhs)); if (did_simplify) { replaced = replace_termcodes(orig_lhs, orig_lhs_len, &bufarg, 0, - flags | REPTERM_NO_SIMPLIFY, NULL, cpo_flags); + flags | REPTERM_NO_SIMPLIFY, NULL, cpo_val); if (replaced == NULL) { return false; } @@ -342,14 +342,14 @@ static bool set_maparg_lhs_rhs(const char *const orig_lhs, const size_t orig_lhs mapargs->alt_lhs_len = 0; } - set_maparg_rhs(orig_rhs, orig_rhs_len, rhs_lua, 0, cpo_flags, mapargs); + set_maparg_rhs(orig_rhs, orig_rhs_len, rhs_lua, 0, cpo_val, mapargs); return true; } /// @see set_maparg_lhs_rhs static void set_maparg_rhs(const char *const orig_rhs, const size_t orig_rhs_len, - const LuaRef rhs_lua, const scid_T sid, const int cpo_flags, + const LuaRef rhs_lua, const scid_T sid, const char *const cpo_val, MapArguments *const mapargs) { mapargs->rhs_lua = rhs_lua; @@ -365,7 +365,7 @@ static void set_maparg_rhs(const char *const orig_rhs, const size_t orig_rhs_len } else { char *rhs_buf = NULL; char *replaced = replace_termcodes(orig_rhs, orig_rhs_len, &rhs_buf, sid, - REPTERM_DO_LT, NULL, cpo_flags); + REPTERM_DO_LT, NULL, cpo_val); mapargs->rhs_len = strlen(replaced); // NB: replace_termcodes may produce an empty string even if orig_rhs is non-empty // (e.g. a single ^V, see :h map-empty-rhs) @@ -492,7 +492,7 @@ static int str_to_mapargs(const char *strargs, bool is_unmap, MapArguments *mapa size_t orig_rhs_len = strlen(rhs_start); if (!set_maparg_lhs_rhs(lhs_to_replace, orig_lhs_len, rhs_start, orig_rhs_len, LUA_NOREF, - CPO_TO_CPO_FLAGS, mapargs)) { + p_cpo, mapargs)) { return 1; } @@ -1103,7 +1103,7 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo char *buf = NULL; const char *const rhs = replace_termcodes(str, strlen(str), &buf, 0, - REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS); + REPTERM_DO_LT, NULL, p_cpo); #define MAPMODE(mode, modechars, chr, modeflags) \ do { \ @@ -1189,16 +1189,16 @@ static bool expand_buffer = false; /// wider than the original description. The caller has to free the string /// afterwards. /// -/// @param cpo_flags Value of various flags present in &cpo +/// @param[in] cpo_val See param docs for @ref replace_termcodes. /// /// @return NULL when there is a problem. -static char *translate_mapping(char *str_in, int cpo_flags) +static char *translate_mapping(const char *const str_in, const char *const cpo_val) { - uint8_t *str = (uint8_t *)str_in; + const uint8_t *str = (const uint8_t *)str_in; garray_T ga; ga_init(&ga, 1, 40); - bool cpo_bslash = cpo_flags & FLAG_CPO_BSLASH; + const bool cpo_bslash = (vim_strchr(cpo_val, CPO_BSLASH) != NULL); for (; *str; str++) { int c = *str; @@ -1377,7 +1377,7 @@ int ExpandMappings(char *pat, regmatch_T *regmatch, int *numMatches, char ***mat continue; } - char *p = translate_mapping(mp->m_keys, CPO_TO_CPO_FLAGS); + char *p = translate_mapping(mp->m_keys, p_cpo); if (p == NULL) { continue; } @@ -1677,7 +1677,7 @@ char *eval_map_expr(mapblock_T *mp, int c) char *res = NULL; if (replace_keycodes) { - replace_termcodes(p, strlen(p), &res, 0, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS); + replace_termcodes(p, strlen(p), &res, 0, REPTERM_DO_LT, NULL, p_cpo); } else { // Escape K_SPECIAL in the result to be able to use the string as typeahead. res = vim_strsave_escape_ks(p); @@ -2168,7 +2168,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) const int mode = get_map_mode((char **)&which, 0); char *keys_simplified = replace_termcodes(keys, strlen(keys), &keys_buf, 0, - flags, &did_simplify, CPO_TO_CPO_FLAGS); + flags, &did_simplify, p_cpo); mapblock_T *mp = NULL; int buffer_local; LuaRef rhs_lua; @@ -2178,7 +2178,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) // When the lhs is being simplified the not-simplified keys are // preferred for printing, like in do_map(). (void)replace_termcodes(keys, strlen(keys), &alt_keys_buf, 0, - flags | REPTERM_NO_SIMPLIFY, NULL, CPO_TO_CPO_FLAGS); + flags | REPTERM_NO_SIMPLIFY, NULL, p_cpo); rhs = check_map(alt_keys_buf, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua); } @@ -2343,14 +2343,14 @@ void f_mapset(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) bool buffer = tv_dict_get_number(d, "buffer") != 0; // mode from the dict is not used - set_maparg_rhs(orig_rhs, strlen(orig_rhs), rhs_lua, sid, CPO_TO_CPO_FLAGS, &args); + set_maparg_rhs(orig_rhs, strlen(orig_rhs), rhs_lua, sid, p_cpo, &args); mapblock_T **map_table = buffer ? curbuf->b_maphash : maphash; mapblock_T **abbr_table = buffer ? &curbuf->b_first_abbr : &first_abbr; // Delete any existing mapping for this lhs and mode. MapArguments unmap_args = MAP_ARGUMENTS_INIT; - set_maparg_lhs_rhs(lhs, strlen(lhs), "", 0, LUA_NOREF, CPO_TO_CPO_FLAGS, &unmap_args); + set_maparg_lhs_rhs(lhs, strlen(lhs), "", 0, LUA_NOREF, p_cpo, &unmap_args); unmap_args.buffer = buffer; buf_do_map(MAPTYPE_UNMAP, &unmap_args, mode, is_abbr, curbuf); xfree(unmap_args.rhs); @@ -2400,7 +2400,7 @@ void f_maplist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) char *lhs = str2special_save(mp->m_keys, true, false); (void)replace_termcodes(lhs, strlen(lhs), &keys_buf, 0, flags, &did_simplify, - CPO_TO_CPO_FLAGS); + p_cpo); xfree(lhs); Dictionary dict = mapblock_fill_dict(mp, @@ -2440,7 +2440,7 @@ void f_mapcheck(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) void add_map(char *lhs, char *rhs, int mode, bool buffer) { MapArguments args = MAP_ARGUMENTS_INIT; - set_maparg_lhs_rhs(lhs, strlen(lhs), rhs, strlen(rhs), LUA_NOREF, 0, &args); + set_maparg_lhs_rhs(lhs, strlen(lhs), rhs, strlen(rhs), LUA_NOREF, p_cpo, &args); args.buffer = buffer; buf_do_map(MAPTYPE_NOREMAP, &args, mode, false, curbuf); @@ -2720,7 +2720,7 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod if (!set_maparg_lhs_rhs(lhs.data, lhs.size, rhs.data, rhs.size, lua_funcref, - CPO_TO_CPO_FLAGS, &parsed_args)) { + p_cpo, &parsed_args)) { api_set_error(err, kErrorTypeValidation, "LHS exceeds maximum map length: %s", lhs.data); goto fail_and_free; } diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 383c9e7817..c4486222a5 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -226,7 +226,7 @@ void ex_menu(exarg_T *eap) } else { map_buf = NULL; map_to = replace_termcodes(map_to, strlen(map_to), &map_buf, 0, - REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS); + REPTERM_DO_LT, NULL, p_cpo); } menuarg.modes = modes; menuarg.noremap[0] = noremap; diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index 86c0dc8367..148620865a 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -872,7 +872,7 @@ int uc_add_command(char *name, size_t name_len, const char *rep, uint32_t argt, char *rep_buf = NULL; garray_T *gap; - replace_termcodes(rep, strlen(rep), &rep_buf, 0, 0, NULL, CPO_TO_CPO_FLAGS); + replace_termcodes(rep, strlen(rep), &rep_buf, 0, 0, NULL, p_cpo); if (rep_buf == NULL) { // Can't replace termcodes - try using the string as is rep_buf = xstrdup(rep); -- cgit From eae6727325111e596b49bb04337a467e8833397c Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 21 Dec 2023 15:57:55 +0100 Subject: refactor: remove os_errmsg and os_msg functions Instead replace them with fprintf and printf. --- src/nvim/ex_cmds.c | 2 +- src/nvim/lua/executor.c | 13 ++--- src/nvim/main.c | 128 ++++++++++++++++++++++-------------------------- src/nvim/message.c | 42 ++-------------- src/nvim/message.h | 7 --- src/nvim/option.c | 6 +-- src/nvim/regexp.c | 16 +++--- 7 files changed, 79 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index a0e9b537e8..9abe347e94 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1486,7 +1486,7 @@ void print_line(linenr_T lnum, int use_number, int list) msg_start(); silent_mode = false; - info_message = true; // use os_msg(), not os_errmsg() + info_message = true; // use stdout, not stderr print_line_no_prefix(lnum, use_number, list); if (save_silent) { msg_putchar('\n'); diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 3e7cdd002e..6289ea3193 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -252,8 +252,7 @@ static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nres if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) { // Terminate this thread, as the main thread may be able to continue // execution. - os_errmsg(e_outofmem); - os_errmsg("\n"); + fprintf(stderr, "%s\n", e_outofmem); lua_close(lstate); #ifdef MSWIN ExitThread(0); @@ -640,8 +639,7 @@ static bool nlua_init_packages(lua_State *lstate, bool is_standalone) lua_getglobal(lstate, "require"); lua_pushstring(lstate, "vim._init_packages"); if (nlua_pcall(lstate, 1, 0)) { - os_errmsg(lua_tostring(lstate, -1)); - os_errmsg("\n"); + fprintf(stderr, "%s\n", lua_tostring(lstate, -1)); return false; } @@ -815,12 +813,12 @@ void nlua_init(char **argv, int argc, int lua_arg0) lua_State *lstate = luaL_newstate(); if (lstate == NULL) { - os_errmsg(_("E970: Failed to initialize lua interpreter\n")); + fprintf(stderr, _("E970: Failed to initialize lua interpreter\n")); os_exit(1); } luaL_openlibs(lstate); if (!nlua_state_init(lstate)) { - os_errmsg(_("E970: Failed to initialize builtin lua modules\n")); + fprintf(stderr, _("E970: Failed to initialize builtin lua modules\n")); #ifdef EXITFREE nlua_common_free_all_mem(lstate); #endif @@ -2307,8 +2305,7 @@ void nlua_init_defaults(void) lua_getglobal(L, "require"); lua_pushstring(L, "vim._defaults"); if (nlua_pcall(L, 1, 0)) { - os_errmsg(lua_tostring(L, -1)); - os_errmsg("\n"); + fprintf(stderr, "%s\n", lua_tostring(L, -1)); } } diff --git a/src/nvim/main.c b/src/nvim/main.c index dfa7c685a0..f01b6ecc8d 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -247,7 +247,7 @@ int main(int argc, char **argv) argv0 = argv[0]; if (!appname_is_valid()) { - os_errmsg("$NVIM_APPNAME must be a name or relative path.\n"); + fprintf(stderr, "$NVIM_APPNAME must be a name or relative path.\n"); exit(1); } @@ -336,7 +336,7 @@ int main(int argc, char **argv) ui_client_forward_stdin = !stdin_isatty; uint64_t rv = ui_client_start_server(params.argc, params.argv); if (!rv) { - os_errmsg("Failed to start Nvim server!\n"); + fprintf(stderr, "Failed to start Nvim server!\n"); os_exit(1); } ui_client_channel_id = rv; @@ -823,8 +823,7 @@ void preserve_exit(const char *errmsg) ui_client_stop(); } if (errmsg != NULL) { - os_errmsg(errmsg); - os_errmsg("\n"); + fprintf(stderr, "%s\n", errmsg); } if (ui_client_channel_id) { os_exit(1); @@ -835,7 +834,7 @@ void preserve_exit(const char *errmsg) FOR_ALL_BUFFERS(buf) { if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) { if (errmsg != NULL) { - os_errmsg("Vim: preserving files...\r\n"); + fprintf(stderr, "Vim: preserving files...\r\n"); } ml_sync_all(false, false, true); // preserve all swap files break; @@ -845,7 +844,7 @@ void preserve_exit(const char *errmsg) ml_close_all(false); // close all memfiles, without deleting if (errmsg != NULL) { - os_errmsg("Vim: Finished.\r\n"); + fprintf(stderr, "Vim: Finished.\r\n"); } getout(1); @@ -910,14 +909,11 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, if (is_ui) { if (!chan) { - os_errmsg("Remote ui failed to start: "); - os_errmsg(connect_error); - os_errmsg("\n"); + fprintf(stderr, "Remote ui failed to start: %s\n", connect_error); os_exit(1); } else if (strequal(server_addr, os_getenv("NVIM"))) { - os_errmsg("Cannot attach UI of :terminal child to its parent. "); - os_errmsg("(Unset $NVIM to skip this check)"); - os_errmsg("\n"); + fprintf(stderr, "%s", "Cannot attach UI of :terminal child to its parent. "); + fprintf(stderr, "%s\n", "(Unset $NVIM to skip this check)"); os_exit(1); } @@ -941,15 +937,14 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, Object o = nlua_exec(s, a, &err); api_free_array(a); if (ERROR_SET(&err)) { - os_errmsg(err.msg); - os_errmsg("\n"); + fprintf(stderr, "%s\n", err.msg); os_exit(2); } if (o.type == kObjectTypeDictionary) { rvobj.data.dictionary = o.data.dictionary; } else { - os_errmsg("vim._cs_remote returned unexpected value\n"); + fprintf(stderr, "vim._cs_remote returned unexpected value\n"); os_exit(2); } @@ -959,34 +954,33 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, for (size_t i = 0; i < rvobj.data.dictionary.size; i++) { if (strequal(rvobj.data.dictionary.items[i].key.data, "errmsg")) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) { - os_errmsg("vim._cs_remote returned an unexpected type for 'errmsg'\n"); + fprintf(stderr, "vim._cs_remote returned an unexpected type for 'errmsg'\n"); os_exit(2); } - os_errmsg(rvobj.data.dictionary.items[i].value.data.string.data); - os_errmsg("\n"); + fprintf(stderr, "%s\n", rvobj.data.dictionary.items[i].value.data.string.data); os_exit(2); } else if (strequal(rvobj.data.dictionary.items[i].key.data, "result")) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) { - os_errmsg("vim._cs_remote returned an unexpected type for 'result'\n"); + fprintf(stderr, "vim._cs_remote returned an unexpected type for 'result'\n"); os_exit(2); } - os_msg(rvobj.data.dictionary.items[i].value.data.string.data); + printf("%s", rvobj.data.dictionary.items[i].value.data.string.data); } else if (strequal(rvobj.data.dictionary.items[i].key.data, "tabbed")) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) { - os_errmsg("vim._cs_remote returned an unexpected type for 'tabbed'\n"); + fprintf(stderr, "vim._cs_remote returned an unexpected type for 'tabbed'\n"); os_exit(2); } tabbed = rvobj.data.dictionary.items[i].value.data.boolean ? kTrue : kFalse; } else if (strequal(rvobj.data.dictionary.items[i].key.data, "should_exit")) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) { - os_errmsg("vim._cs_remote returned an unexpected type for 'should_exit'\n"); + fprintf(stderr, "vim._cs_remote returned an unexpected type for 'should_exit'\n"); os_exit(2); } should_exit = rvobj.data.dictionary.items[i].value.data.boolean ? kTrue : kFalse; } } if (should_exit == kNone || tabbed == kNone) { - os_errmsg("vim._cs_remote didn't return a value for should_exit or tabbed, bailing\n"); + fprintf(stderr, "vim._cs_remote didn't return a value for should_exit or tabbed, bailing\n"); os_exit(2); } api_free_object(o); @@ -1377,7 +1371,7 @@ scripterror: vim_snprintf(IObuff, IOSIZE, _("Attempt to open script file again: \"%s %s\"\n"), argv[-1], argv[0]); - os_errmsg(IObuff); + fprintf(stderr, "%s", IObuff); os_exit(2); } parmp->scriptin = argv[0]; @@ -1614,7 +1608,7 @@ static void open_script_files(mparm_T *parmp) vim_snprintf(IObuff, IOSIZE, _("Cannot open for reading: \"%s\": %s\n"), parmp->scriptin, os_strerror(error)); - os_errmsg(IObuff); + fprintf(stderr, "%s", IObuff); os_exit(2); } } @@ -1624,9 +1618,8 @@ static void open_script_files(mparm_T *parmp) if (parmp->scriptout) { scriptout = os_fopen(parmp->scriptout, parmp->scriptout_append ? APPENDBIN : WRITEBIN); if (scriptout == NULL) { - os_errmsg(_("Cannot open for script output: \"")); - os_errmsg(parmp->scriptout); - os_errmsg("\"\n"); + fprintf(stderr, _("Cannot open for script output: \"")); + fprintf(stderr, "%s\"\n", parmp->scriptout); os_exit(2); } } @@ -2158,17 +2151,12 @@ static void print_mainerr(const char *errstr, const char *str) signal_stop(); // kill us with CTRL-C here, if you like - os_errmsg(prgname); - os_errmsg(": "); - os_errmsg(_(errstr)); + fprintf(stderr, "%s: %s", prgname, _(errstr)); if (str != NULL) { - os_errmsg(": \""); - os_errmsg(str); - os_errmsg("\""); + fprintf(stderr, ": \"%s\"", str); } - os_errmsg(_("\nMore info with \"")); - os_errmsg(prgname); - os_errmsg(" -h\"\n"); + fprintf(stderr, _("\nMore info with \"")); + fprintf(stderr, "%s -h\"\n", prgname); } /// Prints version information for "nvim -v" or "nvim --version". @@ -2176,7 +2164,7 @@ static void version(void) { // TODO(bfred): not like this? nlua_init(NULL, 0, -1); - info_message = true; // use os_msg(), not os_errmsg() + info_message = true; // use stdout, not stderr list_version(); msg_putchar('\n'); msg_didout = false; @@ -2187,38 +2175,38 @@ static void usage(void) { signal_stop(); // kill us with CTRL-C here, if you like - os_msg(_("Usage:\n")); - os_msg(_(" nvim [options] [file ...]\n")); - os_msg(_("\nOptions:\n")); - os_msg(_(" --cmd Execute before any config\n")); - os_msg(_(" +, -c Execute after config and first file\n")); - os_msg(_(" -l