diff options
Diffstat (limited to 'src')
203 files changed, 2014 insertions, 1265 deletions
diff --git a/src/clint.py b/src/clint.py index 1f588322f3..ddd3ff7d44 100755 --- a/src/clint.py +++ b/src/clint.py @@ -880,42 +880,38 @@ 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 # 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", "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,13 +928,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_cmds_defs.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", "src/nvim/globals.h", @@ -946,14 +936,10 @@ 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", @@ -964,21 +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/search.h", - "src/nvim/spell.h", - "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", ] skip_headers = [ @@ -999,12 +975,29 @@ 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') +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. @@ -2292,6 +2285,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/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/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/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/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/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/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 <afile> on cmdline +EXTERN bool autocmd_fname_full INIT( = false); ///< autocmd_fname is full path +EXTERN int autocmd_bufnr INIT( = 0); ///< fnum for <abuf> on cmdline +EXTERN char *autocmd_match INIT( = NULL); ///< name for <amatch> 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/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 <stdint.h> #include <string.h> -#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_defs.h b/src/nvim/buffer_defs.h index e59539f900..7b479e0ec6 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -92,6 +92,22 @@ typedef uint64_t disptick_T; // display tick type #include "nvim/syntax_defs.h" #include "nvim/terminal.h" +typedef enum { + kColorcolBehind = 1, + kColorcolForeground = 2, +} colorcol_flags_T; + +// Structure to define data associated with a colorcolumn. +typedef struct { + int col; // The column number to highlight. + int ch; // The character to draw in the column. + + char* syn_name; // The highlight group name. Must be free'd. + int syn_attr; // The attribute. Will be set before a redraw. + + int flags; // Additional flags +} colorcol_T; + // The taggy struct is used to store the information about a :tag command. typedef struct taggy { char *tagname; // tag name @@ -357,8 +373,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 @@ -542,12 +556,14 @@ struct file_buffer { #ifdef BACKSLASH_IN_FILENAME char *b_p_csl; ///< 'completeslash' #endif + char *b_p_umf; ///< 'usermarkfunc' char *b_p_cfu; ///< 'completefunc' Callback b_cfu_cb; ///< 'completefunc' callback char *b_p_ofu; ///< 'omnifunc' Callback b_ofu_cb; ///< 'omnifunc' callback char *b_p_tfu; ///< 'tagfunc' Callback b_tfu_cb; ///< 'tagfunc' callback + char *b_p_urf; ///< 'userregfunc' int b_p_eof; ///< 'endoffile' int b_p_eol; ///< 'endofline' int b_p_fixeol; ///< 'fixendofline' @@ -904,12 +920,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 +928,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 @@ -1256,7 +1264,7 @@ struct window_S { uint32_t w_p_wbr_flags; // flags for 'winbar' uint32_t w_p_fde_flags; // flags for 'foldexpr' uint32_t w_p_fdt_flags; // flags for 'foldtext' - int *w_p_cc_cols; // array of columns to highlight or NULL + colorcol_T *w_p_cc_cols; // array of columns to highlight or NULL uint8_t w_p_culopt_flags; // flags for cursorline highlighting int w_briopt_min; // minimum width for breakindent 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..9396fdac7f 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -15,13 +15,13 @@ #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" #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/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/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/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/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 <stdbool.h> -#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/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/drawline.c b/src/nvim/drawline.c index e0887ed1d0..c2f0eb9e0e 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -165,12 +165,12 @@ void drawline_free_all_mem(void) /// Advance **color_cols /// /// @return true when there are columns to draw. -static bool advance_color_col(int vcol, int **color_cols) +static bool advance_color_col(int vcol, colorcol_T **color_cols) { - while (**color_cols >= 0 && vcol > **color_cols) { + while ((*color_cols)->col >= 0 && vcol > (*color_cols)->col) { (*color_cols)++; } - return **color_cols >= 0; + return (*color_cols)->col >= 0; } /// Used when 'cursorlineopt' contains "screenline": compute the margins between @@ -1025,7 +1025,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl 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 + colorcol_T *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 @@ -2665,15 +2665,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (draw_color_col) { // 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; color_cols[i].col >= 0; i++) { + if (rightmost_vcol < color_cols[i].col) { + rightmost_vcol = color_cols[i].col; } } } int cuc_attr = win_hl_attr(wp, HLF_CUC); - int mc_attr = win_hl_attr(wp, HLF_MC); int diff_attr = 0; if (wlv.diff_hlf == HLF_TXD) { @@ -2700,8 +2699,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (wp->w_p_cuc && VCOL_HLC == wp->w_virtcol) { col_attr = cuc_attr; - } else if (draw_color_col && VCOL_HLC == *color_cols) { - col_attr = hl_combine_attr(wlv.line_attr_lowprio, mc_attr); + } else if (draw_color_col && VCOL_HLC == color_cols->col) { + col_attr = color_cols->syn_attr; + linebuf_char[wlv.off] = schar_from_char(color_cols->ch); } col_attr = hl_combine_attr(col_attr, wlv.line_attr); @@ -2795,9 +2795,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && 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 (draw_color_col && VCOL_HLC == color_cols->col) { vcol_save_attr = wlv.char_attr; - wlv.char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), wlv.char_attr); + + if (color_cols->flags & kColorcolForeground) { + wlv.char_attr = hl_combine_attr(wlv.char_attr, color_cols->syn_attr); + } else if (!(color_cols->flags & kColorcolBehind)) { + wlv.char_attr = hl_combine_attr(color_cols->syn_attr, wlv.char_attr); + } } } diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 6cc623cb72..659edf2085 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" @@ -1475,6 +1474,19 @@ static void win_update(win_T *wp, DecorProviders *providers) return; } + // Link colorcolumn syn_attrs to syn_names. Needs to be done at a redraw + // as the syn names are volitile and can change. + if (wp->w_p_cc_cols) { + for (int i = 0; wp->w_p_cc_cols[i].col >= 0; ++ i) { + const char* syn_name = wp->w_p_cc_cols[i].syn_name; + if (syn_name == NULL) { + wp->w_p_cc_cols[i].syn_attr = win_hl_attr(wp, HLF_MC); + } else { + wp->w_p_cc_cols[i].syn_attr = syn_name2attr(syn_name); + } + } + } + buf_T *buf = wp->w_buffer; // reset got_int, otherwise regexp won't work 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 <stdbool.h> #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/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..b11f2f2922 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" @@ -36,7 +37,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" @@ -3165,12 +3165,10 @@ static int eval7(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan // Register contents: @r. case '@': (*arg)++; + int regname = mb_cptr2char_adv((const char**) arg); if (evaluate) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = get_reg_contents(**arg, kGRegExprSrc); - } - if (**arg != NUL) { - (*arg)++; + rettv->vval.v_string = get_reg_contents(regname, kGRegExprSrc); } break; @@ -4483,7 +4481,7 @@ bool garbage_collect(bool testing) // registers (ShaDa additional data) { - const void *reg_iter = NULL; + iter_register_T reg_iter = ITER_REGISTER_NULL; do { yankreg_T reg; char name = NUL; @@ -4492,7 +4490,7 @@ bool garbage_collect(bool testing) if (name != NUL) { ABORTING(set_ref_dict)(reg.additional_data, copyID); } - } while (reg_iter != NULL); + } while (reg_iter != ITER_REGISTER_NULL); } // global marks (ShaDa additional data) @@ -4548,7 +4546,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/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 <stddef.h> #include <stdint.h> -#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/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.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/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..7191ad34fc 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" @@ -3166,6 +3165,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) "title", "user-commands", // was accidentally included in 5.4 "user_commands", + "usermarks", "vartabs", "vertsplit", "vimscript-1", @@ -3182,6 +3182,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) "xattr", #endif "nvim", + "rneovim", }; // XXX: eval_has_provider() may shell out :( 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/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/eval/userfunc.c b/src/nvim/eval/userfunc.c index 23b3c4e1b2..3b101454b5 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" @@ -934,6 +933,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett int started_profiling = false; bool did_save_redo = false; save_redo_T save_redo; + char* saved_repeat_cmdline = NULL; // If depth of calling is getting too high, don't execute the function if (depth >= p_mfd) { @@ -946,6 +946,9 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // Save search patterns and redo buffer. save_search_patterns(); if (!ins_compl_active()) { + if (repeat_cmdline) { + saved_repeat_cmdline = xstrdup(repeat_cmdline); + } saveRedobuff(&save_redo); did_save_redo = true; } @@ -1288,6 +1291,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // restore search patterns and redo buffer if (did_save_redo) { restoreRedobuff(&save_redo); + xfree(repeat_cmdline); + repeat_cmdline = saved_repeat_cmdline; } restore_search_patterns(); } diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 2968f75f4d..74d70ca482 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" @@ -553,7 +552,7 @@ const char *skip_var_list(const char *arg, int *var_count, int *semicolon) static const char *skip_var_one(const char *arg) { if (*arg == '@' && arg[1] != NUL) { - return arg + 2; + return arg + 1 + utfc_ptr2len(arg + 1); } return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); @@ -857,16 +856,20 @@ static char *ex_let_register(char *arg, typval_T *const tv, const bool is_const, char *arg_end = NULL; arg++; + + int regname = utf_ptr2char(arg); + int mblen = utf_ptr2len(arg); + if (op != NULL && vim_strchr("+-*/%", (uint8_t)(*op)) != NULL) { semsg(_(e_letwrong), op); } else if (endchars != NULL - && vim_strchr(endchars, (uint8_t)(*skipwhite(arg + 1))) == NULL) { + && vim_strchr(endchars, (uint8_t)(*skipwhite(arg + mblen))) == NULL) { emsg(_(e_letunexp)); } else { char *ptofree = NULL; const char *p = tv_get_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { - char *s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); + char *s = get_reg_contents(*arg == '@' ? '"' : regname, kGRegExprSrc); if (s != NULL) { ptofree = concat_str(s, p); p = ptofree; @@ -874,8 +877,9 @@ static char *ex_let_register(char *arg, typval_T *const tv, const bool is_const, } } if (p != NULL) { - write_reg_contents(*arg == '@' ? '"' : *arg, p, (ssize_t)strlen(p), false); - arg_end = arg + 1; + write_reg_contents(*arg == '@' ? '"' : regname, + p, (ssize_t)strlen(p), false); + arg_end = arg + mblen; } xfree(ptofree); } 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..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" @@ -43,7 +44,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_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 <stdbool.h> - #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.c b/src/nvim/ex_docmd.c index 0b466bbe4e..99e16bae11 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" @@ -3224,7 +3223,7 @@ char *skip_range(const char *cmd, int *ctx) } } if (*cmd != NUL) { - cmd++; + cmd += utf_ptr2len(cmd); } } @@ -3368,13 +3367,13 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int goto error; } if (skip) { - cmd++; + cmd += utfc_ptr2len(cmd); } else { // Only accept a mark in another file when it is // used by itself: ":'M". MarkGet flag = to_other_file && cmd[1] == NUL ? kMarkAll : kMarkBufLocal; - fmark_T *fm = mark_get(curbuf, curwin, NULL, flag, *cmd); - cmd++; + fmark_T *fm = mark_get(curbuf, curwin, NULL, flag, utf_ptr2char(cmd)); + cmd += utf_ptr2len(cmd); if (fm != NULL && fm->fnum != curbuf->handle) { (void)mark_move_to(fm, 0); // Jumped to another file. @@ -7424,7 +7423,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++; } 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.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_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/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/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/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/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 <stdlib.h> - -#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.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/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/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/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 <stdio.h> +#include <stdio.h> // 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/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 <stdint.h> #include <string.h> -#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/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 <afile> on cmdline -EXTERN bool autocmd_fname_full INIT( = false); // autocmd_fname is full path -EXTERN int autocmd_bufnr INIT( = 0); // fnum for <abuf> on cmdline -EXTERN char *autocmd_match INIT( = NULL); // name for <amatch> 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.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 <string.h> #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/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/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.h b/src/nvim/highlight.h index e5d3f3d1ca..ea8a663a9f 100644 --- a/src/nvim/highlight.h +++ b/src/nvim/highlight.h @@ -6,8 +6,99 @@ #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/ui.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" @@ -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 <inttypes.h> - -#include "nvim/macros_defs.h" -#include "nvim/types_defs.h" +#include <stdbool.h> +#include <stdint.h> 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/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..a59ba1b6d9 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -9,6 +9,7 @@ #include <stdlib.h> #include <string.h> +#include "klib/kvec.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" @@ -23,8 +24,8 @@ #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" #include "nvim/getchar.h" #include "nvim/gettext.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); 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/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/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(<sanitizer/asan_interface.h>) +# include <sanitizer/asan_interface.h> // IWYU pragma: keep #endif +// uncrustify:on #ifdef INCLUDE_GENERATED_DECLARATIONS # include "log.h.generated.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/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/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..216e39f3e8 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -26,11 +26,11 @@ #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" #include "nvim/diff.h" +#include "nvim/drawline.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" @@ -42,9 +42,9 @@ #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/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" @@ -97,6 +97,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/map.c b/src/nvim/map.c index be6bf58daa..d7d1a00158 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -118,6 +118,9 @@ void mh_clear(MapHash *h) #define VAL_NAME(x) quasiquote(x, ptr_t) #include "nvim/map_value_impl.c.h" #undef VAL_NAME +#define VAL_NAME(x) quasiquote(x, int) +#include "nvim/map_value_impl.c.h" +#undef VAL_NAME #undef KEY_NAME #define KEY_NAME(x) x##cstr_t diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h index 147c03327a..b6bb172bb0 100644 --- a/src/nvim/map_defs.h +++ b/src/nvim/map_defs.h @@ -152,6 +152,7 @@ KEY_DECLS(HlEntry) KEY_DECLS(ColorKey) MAP_DECLS(int, int) +MAP_DECLS(ptr_t, int) MAP_DECLS(int, ptr_t) MAP_DECLS(cstr_t, ptr_t) MAP_DECLS(cstr_t, int) 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/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/mark.c b/src/nvim/mark.c index 5839cf7a2e..7dacd03891 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -22,6 +22,7 @@ #include "nvim/globals.h" #include "nvim/highlight.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" @@ -37,6 +38,8 @@ #include "nvim/strings.h" #include "nvim/textobject.h" #include "nvim/vim_defs.h" +#include "nvim/map_defs.h" +#include "nvim/eval/userfunc.h" // This file contains routines to maintain and manipulate marks. @@ -46,6 +49,33 @@ // There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing // shada). +static struct { + Map(int, ptr_t) named; +} usermarks; +bool usermarks_init; + +static xfmark_T* lookup_user_mark(int mark) +{ + if (!usermarks_init) { + usermarks.named = (Map(int, ptr_t)) MAP_INIT; + usermarks_init = 1; + } + + bool is_new = false; + xfmark_T **ret = + (xfmark_T**) map_put_ref(int, ptr_t)(&usermarks.named, mark, NULL, &is_new); + + if (ret) { + if (is_new) { + *ret = xcalloc(sizeof(xfmark_T), 1); + } + + return *ret; + } + + return NULL; +} + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mark.c.generated.h" #endif @@ -153,7 +183,8 @@ int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt) RESET_XFMARK(namedfm + i, *pos, fnum, view, NULL); return OK; } - return FAIL; + + return mark_set_user(buf, c); } // Set the previous context mark to the current position and add it to the @@ -334,6 +365,15 @@ fmark_T *mark_get(buf_T *buf, win_T *win, fmark_T *fmp, MarkGet flag, int name) // Local Marks fm = mark_get_local(buf, win, name); } + + if (!fm) { + // Get usermark. + xfmark_T* xm = mark_get_user(buf, name); + if (xm) { + fm = &xm->fmark; + } + } + if (fmp != NULL && fm != NULL) { *fmp = *fm; return fmp; @@ -422,6 +462,123 @@ fmark_T *mark_get_local(buf_T *buf, win_T *win, int name) return mark; } +/// Loads the mark 'out' with the results from calling the usermarkfunc. +/// +/// @param umf String for the usermarkfunc +/// @param name name for the mark +/// @param[out] out the mark to write the results to. +static int call_umf( + const char* umf, int name, typval_T* out, const char* get_or_set_a) +{ + char markname_str[5]; + char get_or_set[4]; + int len; + + strncpy(get_or_set, get_or_set_a, sizeof(get_or_set)); + get_or_set[3] = 0; + + len = (*utf_char2len)(name); + markname_str[len] = 0; + utf_char2bytes(name, markname_str); + + typval_T args[3]; + args[0].v_type = VAR_STRING; + args[1].v_type = VAR_STRING; + args[2].v_type = VAR_UNKNOWN; + + args[0].vval.v_string = get_or_set; + args[1].vval.v_string = markname_str; + + funcexe_T funcexe = FUNCEXE_INIT; + funcexe.fe_evaluate = true; + + return call_func(umf, -1, out, 2, args, &funcexe); +} + +static int typval_to_xfmark(buf_T* buf, xfmark_T* out, typval_T* in) +{ + varnumber_T line; + varnumber_T col; + char* filename = NULL; + + switch (in->v_type) { + case VAR_DICT: + line = tv_dict_get_number(in->vval.v_dict, "line"); + col = tv_dict_get_number(in->vval.v_dict, "col"); + filename = tv_dict_get_string(in->vval.v_dict, "file", true); + break; + + case VAR_NUMBER: + line = in->vval.v_number; + col = 1; + break; + + default: + return -1; + } + + free_xfmark(*out); + memset(out, 0, sizeof(*out)); + + out->fname = filename; + out->fmark.mark.col = (int) col; + out->fmark.mark.lnum = (int) line; + out->fmark.fnum = 0; + out->fmark.timestamp = os_time(); + + return 0; +} + +/// Gets marks that are defined by the user. +/// +/// @param buf the buffer +/// @param name name fo the mark +xfmark_T *mark_get_user(buf_T* buf, int name) +{ + const char* umf = (const char*) buf->b_p_umf; + + if (!umf) { + return NULL; + } + + xfmark_T* mark = lookup_user_mark(name); + if (mark) { + typval_T* typval = xcalloc(sizeof(typval_T), 1); + call_umf(umf, name, typval, "get"); + typval_to_xfmark(buf, mark, typval); + tv_free(typval); + + if (mark->fname) { + buf_T* buffer = + buflist_new( + mark->fname, NULL, mark->fmark.mark.lnum, BLN_CURBUF | BLN_LISTED); + + if (buffer) { + mark->fmark.fnum = buffer->b_fnum; + } + } else { + mark->fmark.fnum = buf->b_fnum; + } + } + + return mark; +} + +int mark_set_user(buf_T* buf, int name) +{ + const char* umf = (const char*) buf->b_p_umf; + + if (!umf) { + return FAIL; + } + + typval_T* out = xcalloc(sizeof(typval_T), 1); + call_umf(umf, name, out, "set"); + tv_free(out); + + return OK; +} + /// Get marks that are actually motions but return them as marks /// /// Gets the following motions as marks: '{', '}', '(', ')' diff --git a/src/nvim/mark.h b/src/nvim/mark.h index 3237ae541e..990be69028 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') @@ -117,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/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/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/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/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.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/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.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/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 <stdbool.h> - #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/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/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/ops.c b/src/nvim/ops.c index 9d0b8e01cd..2ef95f03c4 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -23,6 +23,7 @@ #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/eval/userfunc.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_cmds_defs.h" #include "nvim/ex_getln.h" @@ -62,8 +63,24 @@ #include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" +#include "nvim/yankmap.h" -static yankreg_T y_regs[NUM_REGISTERS] = { 0 }; +struct yank_registers { + yankmap_T inner; +}; + +yank_registers_T y_regs; + +static yankreg_T *get_reg(yank_registers_T *regs, int idx) +{ + return yankmap_get(®s->inner, idx); + +} + +static yankreg_T *get_global_reg(int idx) +{ + return get_reg(&y_regs, idx); +} static yankreg_T *y_previous = NULL; // ptr to last written yankreg @@ -771,6 +788,24 @@ char *get_expr_line_src(void) return xstrdup(expr_line); } + +int get_userreg(int regname) +{ + if ((regname >= 'a' && regname <= 'z') + || (regname >= 'A' && regname <= 'Z') + || (regname >= '0' && regname <= '9') + || (regname <= 127 && strchr("\"-:.%#=*+_/", regname)) + || regname == Ctrl_F + || regname == Ctrl_P + || regname == Ctrl_W + || regname == Ctrl_A + || (regname + USER_REGISTERS_START) < regname) { + return -1; + } + + return regname + USER_REGISTERS_START; +} + /// @return whether `regname` is a valid name of a yank register. /// /// @note: There is no check for 0 (default register), caller should do this. @@ -787,12 +822,156 @@ bool valid_yank_reg(int regname, bool writing) || regname == '-' || regname == '_' || regname == '*' - || regname == '+') { + || regname == '+' + || get_userreg(regname) != -1) { return true; } return false; } +static int call_userreg_put(const char* urf, int regname, typval_T* out) +{ + char regname_str[5]; + int len; + + len = utf_char2len(regname); + regname_str[len] = 0; + utf_char2bytes(regname, regname_str); + + typval_T args[3]; + args[0].v_type = VAR_STRING; + args[1].v_type = VAR_STRING; + args[2].v_type = VAR_NUMBER; + + args[0].vval.v_string = "put"; + args[1].vval.v_string = regname_str; + args[2].vval.v_number = 0; + + funcexe_T funcexe = FUNCEXE_INIT; + funcexe.fe_evaluate = true; + + return call_func( + urf, + -1, + out, + /* argcount_in = */ 3, + args, + &funcexe); +} + +// Converts a typval returned from the userregfunction to a register. +static void typval_to_yankreg(yankreg_T* yankreg, typval_T* val) +{ + if (!yankreg || !val) { + return; + } + + char* type; + dict_T* dict; + typval_T tv; + size_t i; + size_t sz; + + free_register(yankreg); + memset(yankreg, 0, sizeof(*yankreg)); + + switch (val->v_type) { + + case VAR_DICT: + dict = val->vval.v_dict; + type = tv_dict_get_string(dict, "type", false); + + if (!strcmp(type, "block")) { + yankreg->y_width = (int) tv_dict_get_number(dict, "width"); + yankreg->y_type = kMTBlockWise; + } else if (!strcmp(type, "line")) { + yankreg->y_type = kMTLineWise; + } else { + yankreg->y_type = kMTCharWise; + } + + if (tv_dict_get_tv(dict, "lines", &tv) == OK) { + if (tv.v_type == VAR_STRING) { + yankreg->y_array = (char**) xcalloc(sizeof(char*), 1); + yankreg->y_array[0] = strdup(tv.vval.v_string); + } else if (tv.v_type == VAR_LIST) { + yankreg->y_array = + (char**) xcalloc(sizeof(char*), (size_t) tv_list_len(tv.vval.v_list)); + + i = 0; + TV_LIST_ITER_CONST(tv.vval.v_list, li, { + if (li->li_tv.v_type == VAR_STRING) { + yankreg->y_array[i] = strdup(tv_get_string(&li->li_tv)); + } else { + yankreg->y_array[i] = NULL; + } + ++ i; + }); + + yankreg->y_size = i; + } + } else { + yankreg->y_array = NULL; + } + + if (tv_dict_get_tv(dict, "additional_data", &tv) == OK) { + if (tv.v_type == VAR_DICT) { + yankreg->additional_data = tv.vval.v_dict; + } + } + break; + + case VAR_LIST: + yankreg->y_type = kMTLineWise; + sz = (size_t) tv_list_len(val->vval.v_list); + yankreg->y_array = (char**) xcalloc(sizeof(char*), sz); + yankreg->y_size = sz; + i = 0; + TV_LIST_ITER_CONST(val->vval.v_list, li, { + yankreg->y_array[i] = strdup(tv_get_string(&li->li_tv)); + i ++; + }); + break; + + default: + yankreg->y_type = kMTCharWise; + yankreg->y_size = 1; + + if (val->vval.v_string) { + yankreg->y_array = (char**) xcalloc(sizeof(char*), 1); + yankreg->y_array[0] = strdup(tv_get_string(val)); + } else { + yankreg->y_array = NULL; + } + + break; + + } + + yankreg->timestamp = os_time(); +} + +static void copy_userreg(yankreg_T* into, int regname) +{ + if (!into) { + return; + } + + if (!curbuf->b_p_urf || strlen(curbuf->b_p_urf) == 0) { + return; + } + + typval_T* ret = xmalloc(sizeof(typval_T)); + + if (call_userreg_put(curbuf->b_p_urf, regname, ret) == FAIL) { + return; + } + + typval_to_yankreg(into, ret); + + tv_free(ret); +} + /// @return yankreg_T to use, according to the value of `regname`. /// Cannot handle the '_' (black hole) register. /// Must only be called with a valid register name! @@ -830,7 +1009,11 @@ yankreg_T *get_yank_register(int regname, int mode) if (i == -1) { i = 0; } - reg = &y_regs[i]; + reg = get_global_reg(i); + if (get_userreg(regname) != -1 && mode != YREG_YANK) { + // If the mode is not yank, copy the userreg data to the reg. + copy_userreg(reg, regname); + } if (mode == YREG_YANK) { // remember the written register for unnamed paste @@ -856,7 +1039,7 @@ yankreg_T *copy_register(int name) if (copy->y_size == 0) { copy->y_array = NULL; } else { - copy->y_array = xcalloc(copy->y_size, sizeof(char *)); + copy->y_array = (char**) xcalloc(copy->y_size, sizeof(char *)); for (size_t i = 0; i < copy->y_size; i++) { copy->y_array[i] = xstrdup(reg->y_array[i]); } @@ -887,8 +1070,7 @@ int do_record(int c) if (reg_recording == 0) { // start recording - // registers 0-9, a-z and " are allowed - if (c < 0 || (!ASCII_ISALNUM(c) && c != '"')) { + if (c < 0) { retval = FAIL; } else { reg_recording = c; @@ -913,9 +1095,10 @@ int do_record(int c) } // Name of requested register, or empty string for unnamed operation. - char buf[NUMBUFLEN + 2]; - buf[0] = (char)regname; - buf[1] = NUL; + char buf[NUMBUFLEN + 5]; + int len = (*utf_char2len)(regname); + utf_char2bytes(regname, buf); + buf[len] = NUL; (void)tv_dict_add_str(dict, S_LEN("regname"), buf); tv_dict_set_keys_readonly(dict); @@ -992,6 +1175,9 @@ static int stuff_yank(int regname, char *p) reg->y_type = kMTCharWise; } reg->timestamp = os_time(); + if (get_userreg(regname) != -1) { + return eval_yank_userreg(curbuf->b_p_urf, regname, reg); + } return OK; } @@ -1284,6 +1470,90 @@ int insert_reg(int regname, bool literally_arg) return retval; } +/// Converts a yankreg to a dict which can be used as an argument to the +// userregfunc. +static dict_T* yankreg_to_dict(yankreg_T* yankreg) { + dict_T *const dict = tv_dict_alloc(); + dict->dv_refcount = 1; + tv_dict_add_nr(dict, S_LEN("width"), yankreg->y_width); + + const char* type; + + switch(yankreg->y_type) { + case kMTLineWise: + type = "line"; + break; + case kMTCharWise: + type = "char"; + break; + case kMTBlockWise: + type = "block"; + break; + default: + type = "unknown"; + } + + tv_dict_add_str(dict, S_LEN("type"), type); + if (yankreg->additional_data) { + tv_dict_add_dict(dict, S_LEN("additional_data"), yankreg->additional_data); + } + + list_T *const lines = tv_list_alloc((long)yankreg->y_size); + + size_t i; + for (i = 0; i < yankreg->y_size; ++ i) { + tv_list_append_string( + lines, yankreg->y_array[i], (long)strlen(yankreg->y_array[i])); + } + + tv_dict_add_list(dict, S_LEN("lines"), lines); + + return dict; +} + +/* + * Executes the yank() function on a user-defined register to set the contents + * of that register. + */ +static int eval_yank_userreg(const char *ufn, int regname, yankreg_T *reg) +{ + if (!reg) + return -1; + + int ret, len; + char regname_str[5]; + + len = (*utf_char2len)(regname); + regname_str[len] = 0; + utf_char2bytes(regname, regname_str); + + typval_T args[4]; + args[0].v_type = VAR_STRING; + args[1].v_type = VAR_STRING; + args[2].v_type = VAR_DICT; + args[3].v_type = VAR_UNKNOWN; + + args[0].vval.v_string = "yank"; + args[1].vval.v_string = regname_str; + args[2].vval.v_dict = yankreg_to_dict(reg); + + funcexe_T funcexe = FUNCEXE_INIT; + funcexe.fe_evaluate = true; + + typval_T* out = xmalloc(sizeof(typval_T)); + return call_func( + ufn, + -1, + out, + /* argcount_in = */ 3, + args, + &funcexe + ); + + tv_free(out); + return ret; +} + /// If "regname" is a special register, return true and store a pointer to its /// value in "argp". /// @@ -1367,6 +1637,9 @@ bool get_spec_reg(int regname, char **argp, bool *allocated, bool errmsg) case '_': // black hole: always empty *argp = ""; return true; + + default: + break; } return false; @@ -1413,14 +1686,14 @@ bool cmdline_paste_reg(int regname, bool literally_arg, bool remcr) /// Shift the delete registers: "9 is cleared, "8 becomes "9, etc. static void shift_delete_registers(bool y_append) { - free_register(&y_regs[9]); // free register "9 + free_register(get_global_reg(9)); // free register "9 for (int n = 9; n > 1; n--) { - y_regs[n] = y_regs[n - 1]; + *get_global_reg(n) = *get_global_reg(n - 1); } if (!y_append) { - y_previous = &y_regs[1]; + y_previous = get_global_reg(1); } - y_regs[1].y_array = NULL; // set register "1 to empty + get_global_reg(1)->y_array = NULL; // set register "1 to empty } /// Handle a delete operation. @@ -1513,7 +1786,7 @@ int op_delete(oparg_T *oap) if (oap->motion_type == kMTLineWise || oap->line_count > 1 || oap->use_reg_one) { shift_delete_registers(is_append_register(oap->regname)); - reg = &y_regs[1]; + reg = get_global_reg(1); op_yank_reg(oap, false, reg, false); did_yank = true; } @@ -2520,11 +2793,20 @@ int op_change(oparg_T *oap) return retval; } + +/* + * set all the yank registers to empty (called from main()) + */ +void init_yank(void) +{ + init_yankmap(&y_regs.inner); +} + #if defined(EXITFREE) void clear_registers(void) { for (int i = 0; i < NUM_REGISTERS; i++) { - free_register(&y_regs[i]); + free_register(get_global_reg(i)); } } @@ -2570,6 +2852,14 @@ bool op_yank(oparg_T *oap, bool message) yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK); op_yank_reg(oap, message, reg, is_append_register(oap->regname)); + + if (get_userreg(oap->regname) != -1) { + if (eval_yank_userreg(curbuf->b_p_urf, oap->regname, reg) == -1) { + beep_flush(); + return false; + } + } + set_clipboard(oap->regname, reg); do_autocmd_textyankpost(oap, reg); @@ -2748,7 +3038,11 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) if (oap->regname == NUL) { *namebuf = NUL; } else { - vim_snprintf(namebuf, sizeof(namebuf), _(" into \"%c"), oap->regname); + char buf[5]; + int len = (*utf_char2len) (oap->regname); + utf_char2bytes(oap->regname, buf); + buf[len] = 0; + vim_snprintf(namebuf, sizeof(namebuf), _(" into \"%s"), buf); } // redisplay now, so message is not deleted @@ -2818,6 +3112,7 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) FUNC_ATTR_NONNULL_ALL { static bool recursive = false; + int len; if (recursive || !has_event(EVENT_TEXTYANKPOST)) { // No autocommand was defined, or we yanked from this autocommand. @@ -2839,13 +3134,15 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); // Register type. - char buf[NUMBUFLEN + 2]; + char buf[NUMBUFLEN + 6]; format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf)); (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); // Name of requested register, or empty string for unnamed operation. - buf[0] = (char)oap->regname; - buf[1] = NUL; + len = (*utf_char2len)(oap->regname); + buf[len] = 0; + utf_char2bytes(oap->regname, buf); + recursive = true; (void)tv_dict_add_str(dict, S_LEN("regname"), buf); // Motion type: inclusive or exclusive. @@ -3100,6 +3397,10 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) reg = get_yank_register(regname, YREG_PASTE); } + if (get_userreg(regname) != -1) { + copy_userreg(reg, regname); + } + y_type = reg->y_type; y_width = reg->y_width; y_size = reg->y_size; @@ -3778,7 +4079,7 @@ int get_register_name(int num) /// @return the index of the register "" points to. int get_unname_register(void) { - return y_previous == NULL ? -1 : (int)(y_previous - &y_regs[0]); + return yankmap_find(&y_regs.inner, y_previous); } /// ":dis" and ":registers": Display the contents of the yank registers. @@ -3815,10 +4116,10 @@ void ex_display(exarg_T *eap) if (y_previous != NULL) { yb = y_previous; } else { - yb = &(y_regs[0]); + yb = get_global_reg(0); } } else { - yb = &(y_regs[i]); + yb = get_global_reg(i); } get_clipboard(name, &yb, true); @@ -5011,6 +5312,10 @@ static yankreg_T *init_write_reg(int name, yankreg_T **old_y_previous, bool must static void finish_write_reg(int name, yankreg_T *reg, yankreg_T *old_y_previous) { + if (get_userreg(name) != -1) { + eval_yank_userreg(curbuf->b_p_urf, name, reg); + } + // Send text of clipboard register to the clipboard. set_clipboard(name, reg); @@ -6463,7 +6768,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) } if (explicit_cb_reg) { - target = &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER]; + target = get_global_reg(*name == '*' ? STAR_REGISTER : PLUS_REGISTER); if (writing && (cb_flags & (*name == '*' ? CB_UNNAMED : CB_UNNAMEDPLUS))) { clipboard_needs_update = false; } @@ -6480,10 +6785,10 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) if (cb_flags & CB_UNNAMEDPLUS) { *name = (cb_flags & CB_UNNAMED && writing) ? '"' : '+'; - target = &y_regs[PLUS_REGISTER]; + target = get_global_reg(PLUS_REGISTER); } else { *name = '*'; - target = &y_regs[STAR_REGISTER]; + target = get_global_reg(STAR_REGISTER); } goto end; } @@ -6799,11 +7104,11 @@ static inline bool reg_empty(const yankreg_T *const reg) /// Iterate over global registers. /// /// @see op_register_iter -const void *op_global_reg_iter(const void *const iter, char *const name, yankreg_T *const reg, - bool *is_unnamed) +iter_register_T op_global_reg_iter(iter_register_T iter, char *const name, + yankreg_T *const reg, bool *is_unnamed) FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT { - return op_reg_iter(iter, y_regs, name, reg, is_unnamed); + return op_reg_iter(iter, &y_regs, name, reg, is_unnamed); } /// Iterate over registers `regs`. @@ -6815,30 +7120,33 @@ const void *op_global_reg_iter(const void *const iter, char *const name, yankreg /// /// @return Pointer that must be passed to next `op_register_iter` call or /// NULL if iteration is over. -const void *op_reg_iter(const void *const iter, const yankreg_T *const regs, char *const name, - yankreg_T *const reg, bool *is_unnamed) +iter_register_T op_reg_iter(iter_register_T iter, yank_registers_T *regs, + char *const name, yankreg_T *const reg, + bool *is_unnamed) FUNC_ATTR_NONNULL_ARG(3, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { *name = NUL; - const yankreg_T *iter_reg = (iter == NULL - ? &(regs[0]) - : (const yankreg_T *const)iter); - while (iter_reg - &(regs[0]) < NUM_SAVED_REGISTERS && reg_empty(iter_reg)) { - iter_reg++; + int iter_idx = (int)(iter == ITER_REGISTER_NULL ? 0 : iter - 1); + + while (iter_idx < NUM_SAVED_REGISTERS && reg_empty(get_reg(regs, iter_idx))) { + ++iter_idx; } - if (iter_reg - &(regs[0]) == NUM_SAVED_REGISTERS || reg_empty(iter_reg)) { - return NULL; + + if (iter_idx >= NUM_SAVED_REGISTERS || reg_empty(get_reg(regs, iter_idx))) { + return ITER_REGISTER_NULL; } - int iter_off = (int)(iter_reg - &(regs[0])); - *name = (char)get_register_name(iter_off); - *reg = *iter_reg; - *is_unnamed = (iter_reg == y_previous); - while (++iter_reg - &(regs[0]) < NUM_SAVED_REGISTERS) { - if (!reg_empty(iter_reg)) { - return (void *)iter_reg; + + *reg = *get_reg(regs, iter_idx); + *name = (char) get_register_name(iter_idx); + *is_unnamed = (get_reg(regs, iter_idx) == y_previous); + + while (++iter_idx < NUM_SAVED_REGISTERS) { + if (!reg_empty(get_reg(regs, iter_idx))) { + return iter_idx + 1; } } - return NULL; + + return ITER_REGISTER_NULL; } /// Get a number of non-empty registers @@ -6846,8 +7154,8 @@ size_t op_reg_amount(void) FUNC_ATTR_WARN_UNUSED_RESULT { size_t ret = 0; - for (size_t i = 0; i < NUM_SAVED_REGISTERS; i++) { - if (!reg_empty(y_regs + i)) { + for (int i = 0; i < NUM_SAVED_REGISTERS; i++) { + if (!reg_empty(get_global_reg(i))) { ret++; } } @@ -6867,11 +7175,11 @@ bool op_reg_set(const char name, const yankreg_T reg, bool is_unnamed) if (i == -1) { return false; } - free_register(&y_regs[i]); - y_regs[i] = reg; + free_register(get_global_reg(i)); + *get_global_reg(i) = reg; if (is_unnamed) { - y_previous = &y_regs[i]; + y_previous = get_global_reg(i); } return true; } @@ -6887,7 +7195,7 @@ const yankreg_T *op_reg_get(const char name) if (i == -1) { return NULL; } - return &y_regs[i]; + return get_global_reg(i); } /// Set the previous yank register @@ -6902,7 +7210,7 @@ bool op_reg_set_previous(const char name) return false; } - y_previous = &y_regs[i]; + y_previous = get_global_reg(i); return true; } diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 67a613cbca..519b946f6d 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -19,6 +19,7 @@ typedef int (*Indenter)(void); /// flags for do_put() enum { + ITER_REGISTER_NULL = 0, PUT_FIXINDENT = 1, ///< make indent look nice PUT_CURSEND = 2, ///< leave cursor after end of new text PUT_CURSLINE = 4, ///< leave cursor on last line of new text @@ -42,6 +43,7 @@ enum { STAR_REGISTER = 37, PLUS_REGISTER = 38, NUM_REGISTERS = 39, + USER_REGISTERS_START = 39 }; /// Operator IDs; The order must correspond to opchars[] in ops.c! @@ -101,6 +103,11 @@ typedef enum { YREG_YANK, YREG_PUT, } yreg_mode_t; +/// Returns a reference to a user-defined register. +int get_userreg(const int regname); + +static inline int op_reg_index(int regname) + REAL_FATTR_CONST; /// Convert register name into register index /// @@ -108,7 +115,6 @@ typedef enum { /// /// @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'; @@ -123,15 +129,22 @@ static inline int op_reg_index(const int regname) } else if (regname == '+') { return PLUS_REGISTER; } else { - return -1; + return get_userreg(regname); } } +static inline bool is_literal_register(int regname) + REAL_FATTR_CONST; + +struct yank_registers; +typedef struct yank_registers yank_registers_T; + +typedef size_t iter_register_T; + /// @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..fd4f1eb50f 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -24,8 +24,6 @@ #include <stdlib.h> #include <string.h> -#include "auto/config.h" -#include "klib/kvec.h" #include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" @@ -49,7 +47,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" @@ -99,22 +96,20 @@ #include "nvim/vim_defs.h" #include "nvim/window.h" +#include "auto/config.h" +#include "klib/kvec.h" + #ifdef BACKSLASH_IN_FILENAME # include "nvim/arglist.h" #endif -static const char e_unknown_option[] - = N_("E518: Unknown option"); -static const char e_not_allowed_in_modeline[] - = N_("E520: Not allowed in a modeline"); +static const char e_unknown_option[] = N_("E518: Unknown option"); +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[] - = N_("E590: A preview window already exists"); +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[] = N_("E590: A preview window already exists"); static char *p_term = NULL; static char *p_ttytype = NULL; @@ -157,13 +152,10 @@ typedef enum { # include "options.generated.h" #endif -static char *(p_bin_dep_opts[]) = { - "textwidth", "wrapmargin", "modeline", "expandtab", NULL -}; -static char *(p_paste_dep_opts[]) = { - "autoindent", "expandtab", "ruler", "showmatch", "smarttab", - "softtabstop", "textwidth", "wrapmargin", "revins", "varsofttabstop", NULL -}; +static char *(p_bin_dep_opts[]) = { "textwidth", "wrapmargin", "modeline", "expandtab", NULL }; +static char *(p_paste_dep_opts[]) + = { "autoindent", "expandtab", "ruler", "showmatch", "smarttab", "softtabstop", + "textwidth", "wrapmargin", "revins", "varsofttabstop", NULL }; void set_init_tablocal(void) { @@ -226,8 +218,7 @@ static void set_init_default_backupskip(void) xstrlcpy(item, p, len); add_pathsep(item); xstrlcat(item, "*", len); - if (find_dup_item(ga.ga_data, item, options[opt_idx].flags) - == NULL) { + if (find_dup_item(ga.ga_data, item, options[opt_idx].flags) == NULL) { ga_grow(&ga, (int)len); if (!GA_EMPTY(&ga)) { STRCAT(ga.ga_data, ","); @@ -257,7 +248,7 @@ static void set_init_default_cdpath(void) } char *buf = xmalloc(2 * strlen(cdpath) + 2); - buf[0] = ','; // start with ",", current dir first + buf[0] = ','; // start with ",", current dir first int j = 1; for (int i = 0; cdpath[i] != NUL; i++) { if (vim_ispathlistsep(cdpath[i])) { @@ -275,7 +266,7 @@ static void set_init_default_cdpath(void) options[opt_idx].def_val = buf; options[opt_idx].flags |= P_DEF_ALLOCED; } else { - xfree(buf); // cannot happen + xfree(buf); // cannot happen } xfree(cdpath); } @@ -348,12 +339,9 @@ void set_init_1(bool clean_arg) 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), - true); - set_string_default("directory", stdpaths_user_state_subpath("swap", 2, true), - true); - set_string_default("undodir", stdpaths_user_state_subpath("undo", 2, true), - true); + set_string_default("viewdir", stdpaths_user_state_subpath("view", 2, true), true); + set_string_default("directory", stdpaths_user_state_subpath("swap", 2, true), true); + set_string_default("undodir", 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); @@ -369,7 +357,7 @@ void set_init_1(bool clean_arg) set_options_default(0); curbuf->b_p_initialized = true; - curbuf->b_p_ar = -1; // no local 'autoread' value + curbuf->b_p_ar = -1; // no local 'autoread' value curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL; check_buf_options(curbuf); check_win_options(curwin); @@ -391,7 +379,7 @@ void set_init_1(bool clean_arg) // Expand environment variables and things like "~" for the defaults. set_init_expand_env(); - save_file_ff(curbuf); // Buffer is unchanged + save_file_ff(curbuf); // Buffer is unchanged // Detect use of mlterm. // Mlterm is a terminal emulator akin to xterm that has some special @@ -429,7 +417,7 @@ static void set_option_default(const int opt_idx, int opt_flags) vimoption_T *opt = &options[opt_idx]; 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 (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. @@ -447,8 +435,7 @@ static void set_option_default(const int opt_idx, int opt_flags) win_comp_scroll(curwin); } else { OptInt def_val = (OptInt)(intptr_t)opt->def_val; - if ((OptInt *)varp == &curwin->w_p_so - || (OptInt *)varp == &curwin->w_p_siso) { + if ((OptInt *)varp == &curwin->w_p_so || (OptInt *)varp == &curwin->w_p_siso) { // 'scrolloff' and 'sidescrolloff' local values have a // different default value than the global default. *(OptInt *)varp = -1; @@ -470,8 +457,7 @@ static void set_option_default(const int opt_idx, int opt_flags) #endif // May also set global value for local option. if (both) { - *(int *)get_varp_scope(opt, OPT_GLOBAL) = - *(int *)varp; + *(int *)get_varp_scope(opt, OPT_GLOBAL) = *(int *)varp; } } @@ -508,8 +494,7 @@ static void set_options_default(int opt_flags) /// @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) - FUNC_ATTR_NONNULL_ALL +static void set_string_default(const char *name, char *val, bool allocated) FUNC_ATTR_NONNULL_ALL { int opt_idx = findoption(name); if (opt_idx >= 0) { @@ -544,8 +529,7 @@ static char *find_dup_item(char *origval, const char *newval, uint32_t flags) // Count backslashes. Only a comma with an even number of backslashes // or a single backslash preceded by a comma before it is recognized as // a separator. - if ((s > origval + 1 && s[-1] == '\\' && s[-2] != ',') - || (s == origval + 1 && s[-1] == '\\')) { + if ((s > origval + 1 && s[-1] == '\\' && s[-2] != ',') || (s == origval + 1 && s[-1] == '\\')) { bs++; } else { bs = 0; @@ -612,19 +596,15 @@ void set_init_2(bool headless) /// Initialize the options, part three: After reading the .vimrc void set_init_3(void) { - parse_shape_opt(SHAPE_CURSOR); // set cursor shapes from 'guicursor' + parse_shape_opt(SHAPE_CURSOR); // set cursor shapes from 'guicursor' // 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 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_sp = (idx_sp < 0) ? false : !(options[idx_sp].flags & P_WAS_SET); size_t len = 0; char *p = (char *)invocation_path_tail(p_sh, &len); @@ -635,8 +615,7 @@ void set_init_3(void) // Default for p_sp is "| tee", for p_srr is ">". // For known shells it is changed here to include stderr. // - if (path_fnamecmp(p, "csh") == 0 - || path_fnamecmp(p, "tcsh") == 0) { + if (path_fnamecmp(p, "csh") == 0 || path_fnamecmp(p, "tcsh") == 0) { if (do_sp) { p_sp = "|& tee"; options[idx_sp].def_val = p_sp; @@ -645,16 +624,11 @@ void set_init_3(void) p_srr = ">&"; options[idx_srr].def_val = p_srr; } - } else if (path_fnamecmp(p, "sh") == 0 - || path_fnamecmp(p, "ksh") == 0 - || path_fnamecmp(p, "mksh") == 0 - || path_fnamecmp(p, "pdksh") == 0 - || path_fnamecmp(p, "zsh") == 0 - || path_fnamecmp(p, "zsh-beta") == 0 - || path_fnamecmp(p, "bash") == 0 - || path_fnamecmp(p, "fish") == 0 - || path_fnamecmp(p, "ash") == 0 - || path_fnamecmp(p, "dash") == 0) { + } else if (path_fnamecmp(p, "sh") == 0 || path_fnamecmp(p, "ksh") == 0 + || path_fnamecmp(p, "mksh") == 0 || path_fnamecmp(p, "pdksh") == 0 + || path_fnamecmp(p, "zsh") == 0 || path_fnamecmp(p, "zsh-beta") == 0 + || path_fnamecmp(p, "bash") == 0 || path_fnamecmp(p, "fish") == 0 + || path_fnamecmp(p, "ash") == 0 || path_fnamecmp(p, "dash") == 0) { // Always use POSIX shell style redirection if we reach this if (do_sp) { p_sp = "2>&1| tee"; @@ -796,13 +770,10 @@ static char *stropt_copy_value(char *origval, char **argp, set_op_T op, while (*arg != NUL && !ascii_iswhite(*arg)) { if (*arg == '\\' && arg[1] != NUL #ifdef BACKSLASH_IN_FILENAME - && !((flags & P_EXPAND) - && vim_isfilec((uint8_t)arg[1]) - && !ascii_iswhite(arg[1]) - && (arg[1] != '\\' - || (s == newval && arg[2] != '\\'))) + && !((flags & P_EXPAND) && vim_isfilec((uint8_t)arg[1]) && !ascii_iswhite(arg[1]) + && (arg[1] != '\\' || (s == newval && arg[2] != '\\'))) #endif - ) { + ) { arg++; // remove backslash } int i = utfc_ptr2len(arg); @@ -849,9 +820,7 @@ static void stropt_concat_with_comma(char *origval, char *newval, set_op_T op, u if (op == OP_ADDING) { len = (int)strlen(origval); // Strip a trailing comma, would get 2. - if (comma && len > 1 - && (flags & P_ONECOMMA) == P_ONECOMMA - && origval[len - 1] == ',' + if (comma && len > 1 && (flags & P_ONECOMMA) == P_ONECOMMA && origval[len - 1] == ',' && origval[len - 2] != '\\') { len--; } @@ -899,15 +868,13 @@ static void stropt_remove_dupflags(char *newval, uint32_t flags) for (s = newval; *s;) { // if options have P_FLAGLIST and P_ONECOMMA such as 'whichwrap' if (flags & P_ONECOMMA) { - if (*s != ',' && *(s + 1) == ',' - && vim_strchr(s + 2, (uint8_t)(*s)) != NULL) { + if (*s != ',' && *(s + 1) == ',' && vim_strchr(s + 2, (uint8_t)(*s)) != NULL) { // Remove the duplicated value and the next comma. STRMOVE(s, s + 2); continue; } } else { - if ((!(flags & P_COMMA) || *s != ',') - && vim_strchr(s + 1, (uint8_t)(*s)) != NULL) { + if ((!(flags & P_COMMA) || *s != ',') && vim_strchr(s + 1, (uint8_t)(*s)) != NULL) { STRMOVE(s, s + 1); continue; } @@ -1001,11 +968,11 @@ static set_op_T get_op(const char *arg) set_op_T op = OP_NONE; if (*arg != NUL && *(arg + 1) == '=') { if (*arg == '+') { - op = OP_ADDING; // "+=" + op = OP_ADDING; // "+=" } else if (*arg == '^') { - op = OP_PREPENDING; // "^=" + op = OP_PREPENDING; // "^=" } else if (*arg == '-') { - op = OP_REMOVING; // "-=" + op = OP_REMOVING; // "-=" } } return op; @@ -1091,14 +1058,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)) { + if ((opt_flags & OPT_WINONLY) && (opt_idx < 0 || 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 - && options[opt_idx].var == VAR_WIN) { + if ((opt_flags & OPT_NOWIN) && opt_idx >= 0 && options[opt_idx].var == VAR_WIN) { return FAIL; } @@ -1115,10 +1080,8 @@ static int validate_opt_idx(win_T *win, int opt_idx, int opt_flags, uint32_t fla // In diff mode some options are overruled. This avoids that // 'foldmethod' becomes "marker" instead of "diff" and that // "wrap" gets set. - if (win->w_p_diff - && opt_idx >= 0 // shut up coverity warning - && (options[opt_idx].indir == PV_FDM - || options[opt_idx].indir == PV_WRAP)) { + if (win->w_p_diff && opt_idx >= 0 // shut up coverity warning + && (options[opt_idx].indir == PV_FDM || options[opt_idx].indir == PV_WRAP)) { return FAIL; } } @@ -1135,8 +1098,8 @@ 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, 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 + const size_t errbuflen, + const char **errmsg) FUNC_ATTR_WARN_UNUSED_RESULT { assert(varp != NULL); @@ -1294,21 +1257,20 @@ 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 == -1 && key == 0) { // found a mismatch: skip *errmsg = e_unknown_option; return; } - uint32_t flags; // flags for current option + uint32_t flags; // flags for current option void *varp = NULL; // pointer to variable for current option if (opt_idx >= 0) { - if (options[opt_idx].var == NULL) { // hidden option: skip + 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 == '?')) { + && (!(options[opt_idx].flags & P_BOOL) || nextchar == '?')) { *errmsg = e_unsupportedoption; } return; @@ -1333,8 +1295,7 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * *argp += 2; } } - if (vim_strchr("?!&<", nextchar) != NULL - && (*argp)[1] != NUL && !ascii_iswhite((*argp)[1])) { + if (vim_strchr("?!&<", nextchar) != NULL && (*argp)[1] != NUL && !ascii_iswhite((*argp)[1])) { *errmsg = e_trailing; return; } @@ -1345,15 +1306,13 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * // '=' character per "set" command line. grrr. (jw) // if (nextchar == '?' - || (prefix == PREFIX_NONE - && vim_strchr("=:&<", nextchar) == NULL - && !(flags & P_BOOL))) { + || (prefix == PREFIX_NONE && vim_strchr("=:&<", nextchar) == NULL && !(flags & P_BOOL))) { // print value if (*did_show) { - msg_putchar('\n'); // cursor below last one + msg_putchar('\n'); // cursor below last one } else { - gotocmdline(true); // cursor at status line - *did_show = true; // remember that we did a line + gotocmdline(true); // cursor at status line + *did_show = true; // remember that we did a line } if (opt_idx >= 0) { showoneopt(&options[opt_idx], opt_flags); @@ -1426,15 +1385,14 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char * /// @return FAIL if an error is detected, OK otherwise int do_set(char *arg, int opt_flags) { - bool did_show = false; // already showed one value + bool did_show = false; // already showed one value if (*arg == NUL) { showoptions(false, opt_flags); did_show = true; } else { - while (*arg != NUL) { // loop to process all options - if (strncmp(arg, "all", 3) == 0 && !ASCII_ISALPHA(arg[3]) - && !(opt_flags & OPT_MODELINE)) { + while (*arg != NUL) { // loop to process all options + if (strncmp(arg, "all", 3) == 0 && !ASCII_ISALPHA(arg[3]) && !(opt_flags & OPT_MODELINE)) { // ":set all" show all options. // ":set all&" set all options to their default value. arg += 3; @@ -1451,7 +1409,7 @@ int do_set(char *arg, int opt_flags) did_show = true; } } else { - char *startarg = arg; // remember for error message + char *startarg = arg; // remember for error message const char *errmsg = NULL; char errbuf[80]; @@ -1482,8 +1440,8 @@ int do_set(char *arg, int opt_flags) // make sure all characters are printable trans_characters(IObuff, IOSIZE); - no_wait_return++; // wait_return() done later - emsg(IObuff); // show error highlighted + no_wait_return++; // wait_return() done later + emsg(IObuff); // show error highlighted no_wait_return--; return FAIL; @@ -1497,10 +1455,10 @@ int do_set(char *arg, int opt_flags) if (silent_mode && did_show) { // After displaying option values in silent mode. silent_mode = false; - info_message = true; // use os_msg(), not os_errmsg() + info_message = true; // use os_msg(), not os_errmsg() msg_putchar('\n'); silent_mode = true; - info_message = false; // use os_msg(), not os_errmsg() + info_message = false; // use os_msg(), not os_errmsg() } return OK; @@ -1538,7 +1496,7 @@ void set_options_bin(int oldval, int newval, int opt_flags) // The option values that are changed when 'bin' changes are // copied when 'bin is set and restored when 'bin' is reset. if (newval) { - if (!oldval) { // switched on + if (!oldval) { // switched on if (!(opt_flags & OPT_GLOBAL)) { curbuf->b_p_tw_nobin = curbuf->b_p_tw; curbuf->b_p_wm_nobin = curbuf->b_p_wm; @@ -1554,19 +1512,19 @@ void set_options_bin(int oldval, int newval, int opt_flags) } if (!(opt_flags & OPT_GLOBAL)) { - curbuf->b_p_tw = 0; // no automatic line wrap - curbuf->b_p_wm = 0; // no automatic line wrap - curbuf->b_p_ml = 0; // no modelines - curbuf->b_p_et = 0; // no expandtab + curbuf->b_p_tw = 0; // no automatic line wrap + curbuf->b_p_wm = 0; // no automatic line wrap + curbuf->b_p_ml = 0; // no modelines + curbuf->b_p_et = 0; // no expandtab } if (!(opt_flags & OPT_LOCAL)) { p_tw = 0; p_wm = 0; p_ml = false; p_et = false; - p_bin = true; // needed when called for the "-b" argument + p_bin = true; // needed when called for the "-b" argument } - } else if (oldval) { // switched off + } else if (oldval) { // switched off if (!(opt_flags & OPT_GLOBAL)) { curbuf->b_p_tw = curbuf->b_p_tw_nobin; curbuf->b_p_wm = curbuf->b_p_wm_nobin; @@ -1608,11 +1566,11 @@ char *find_shada_parameter(int type) if (*p == type) { return p + 1; } - if (*p == 'n') { // 'n' is always the last one + if (*p == 'n') { // 'n' is always the last one break; } - p = vim_strchr(p, ','); // skip until next ',' - if (p == NULL) { // hit the end without finding parameter + p = vim_strchr(p, ','); // skip until next ',' + if (p == NULL) { // hit the end without finding parameter break; } } @@ -1644,11 +1602,9 @@ static char *option_expand(int opt_idx, char *val) // Escape spaces when expanding 'tags', they are used to separate file // names. // For 'spellsuggest' expand after "file:". - expand_env_esc(val, NameBuff, MAXPATHL, - (char **)options[opt_idx].var == &p_tags, false, - (char **)options[opt_idx].var == &p_sps ? "file:" - : NULL); - if (strcmp(NameBuff, val) == 0) { // they are the same + expand_env_esc(val, NameBuff, MAXPATHL, (char **)options[opt_idx].var == &p_tags, false, + (char **)options[opt_idx].var == &p_sps ? "file:" : NULL); + if (strcmp(NameBuff, val) == 0) { // they are the same return NULL; } @@ -1692,7 +1648,7 @@ static void didset_options2(void) xfree(curbuf->b_p_vsts_array); (void)tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array); xfree(curbuf->b_p_vts_array); - (void)tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array); + (void)tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array); } /// Check for string options that are NULL (normally only termcap options). @@ -1763,8 +1719,7 @@ bool valid_name(const char *val, const char *allowed) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { for (const char *s = val; *s != NUL; s++) { - if (!ASCII_ISALNUM(*s) - && vim_strchr(allowed, (uint8_t)(*s)) == NULL) { + if (!ASCII_ISALNUM(*s) && vim_strchr(allowed, (uint8_t)(*s)) == NULL) { return false; } } @@ -1773,8 +1728,7 @@ bool valid_name(const char *val, const char *allowed) void check_blending(win_T *wp) { - wp->w_grid_alloc.blending = - wp->w_p_winbl > 0 || (wp->w_floating && wp->w_float_config.shadow); + wp->w_grid_alloc.blending = wp->w_p_winbl > 0 || (wp->w_floating && wp->w_float_config.shadow); } /// Handle setting `winhighlight' in window "wp" @@ -1858,7 +1812,7 @@ void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx) // Remember where the option was set. For local options need to do that // in the buffer or window structure. - if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0) { + if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF | PV_WIN)) == 0) { options[opt_idx].last_set = last_set; } if (both || (opt_flags & OPT_LOCAL)) { @@ -2018,8 +1972,7 @@ static const char *did_set_buflisted(optset_T *args) // when 'buflisted' changes, trigger autocommands if (args->os_oldval.boolean != buf->b_p_bl) { - apply_autocmds(buf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, - NULL, NULL, true, buf); + apply_autocmds(buf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, NULL, NULL, true, buf); } return NULL; } @@ -2193,7 +2146,7 @@ static const char *did_set_lisp(optset_T *args) { buf_T *buf = (buf_T *)args->os_buf; // When 'lisp' option changes include/exclude '-' in keyword characters. - (void)buf_init_chartab(buf, false); // ignore errors + (void)buf_init_chartab(buf, false); // ignore errors return NULL; } @@ -2262,9 +2215,8 @@ static const char *did_set_paste(optset_T *args FUNC_ATTR_UNUSED) if (buf->b_p_vsts_nopaste) { xfree(buf->b_p_vsts_nopaste); } - buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_string_option - ? xstrdup(buf->b_p_vsts) - : NULL; + buf->b_p_vsts_nopaste + = buf->b_p_vsts && buf->b_p_vsts != empty_string_option ? xstrdup(buf->b_p_vsts) : NULL; } // save global options @@ -2288,11 +2240,11 @@ static const char *did_set_paste(optset_T *args FUNC_ATTR_UNUSED) // already on. // set options for each buffer FOR_ALL_BUFFERS(buf) { - buf->b_p_tw = 0; // textwidth is 0 - buf->b_p_wm = 0; // wrapmargin is 0 - buf->b_p_sts = 0; // softtabstop is 0 - buf->b_p_ai = 0; // no auto-indent - buf->b_p_et = 0; // no expandtab + buf->b_p_tw = 0; // textwidth is 0 + buf->b_p_wm = 0; // wrapmargin is 0 + buf->b_p_sts = 0; // softtabstop is 0 + buf->b_p_ai = 0; // no auto-indent + buf->b_p_et = 0; // no expandtab if (buf->b_p_vsts) { free_string_option(buf->b_p_vsts); } @@ -2301,13 +2253,13 @@ static const char *did_set_paste(optset_T *args FUNC_ATTR_UNUSED) } // set global options - p_sm = 0; // no showmatch - p_sta = 0; // no smarttab + p_sm = 0; // no showmatch + p_sta = 0; // no smarttab if (p_ru) { - status_redraw_all(); // redraw to remove the ruler + status_redraw_all(); // redraw to remove the ruler } - p_ru = 0; // no ruler - p_ri = 0; // no reverse insert + p_ru = 0; // no ruler + p_ri = 0; // no reverse insert // set global values for local buffer options p_tw = 0; p_wm = 0; @@ -2344,7 +2296,7 @@ static const char *did_set_paste(optset_T *args FUNC_ATTR_UNUSED) p_sm = save_sm; p_sta = save_sta; if (p_ru != save_ru) { - status_redraw_all(); // redraw to draw the ruler + status_redraw_all(); // redraw to draw the ruler } p_ru = save_ru; p_ri = save_ri; @@ -2525,11 +2477,11 @@ static const char *did_set_swapfile(optset_T *args) buf_T *buf = (buf_T *)args->os_buf; // when 'swf' is set, create swapfile, when reset remove swapfile if (buf->b_p_swf && p_uc) { - ml_open_file(buf); // create the swap file + ml_open_file(buf); // create the swap file } else { // no need to reset curbuf->b_may_swap, ml_open_file() will check // buf->b_p_swf - mf_close_file(buf, true); // remove the swap file + mf_close_file(buf, true); // remove the swap file } return NULL; } @@ -2582,9 +2534,8 @@ static const char *did_set_undofile(optset_T *args) // only for the current buffer: Try to read in the undofile, // if one exists, the buffer wasn't changed and the buffer was // loaded - if ((curbuf == bp - || (args->os_flags & OPT_GLOBAL) || args->os_flags == 0) - && !bufIsChanged(bp) && bp->b_ml.ml_mfp != NULL) { + if ((curbuf == bp || (args->os_flags & OPT_GLOBAL) || args->os_flags == 0) && !bufIsChanged(bp) + && bp->b_ml.ml_mfp != NULL) { u_compute_hash(bp, hash); u_read_undo(NULL, hash, bp->b_fname); } @@ -2620,9 +2571,9 @@ static const char *did_set_undolevels(optset_T *args) buf_T *buf = (buf_T *)args->os_buf; OptInt *pp = (OptInt *)args->os_varp; - if (pp == &p_ul) { // global 'undolevels' + if (pp == &p_ul) { // global 'undolevels' did_set_global_undolevels(args->os_newval.number, args->os_oldval.number); - } else if (pp == &curbuf->b_p_ul) { // buffer local 'undolevels' + } else if (pp == &curbuf->b_p_ul) { // buffer local 'undolevels' did_set_buflocal_undolevels(buf, args->os_newval.number, args->os_oldval.number); } @@ -2729,8 +2680,8 @@ static void do_syntax_autocmd(buf_T *buf, bool value_changed) syn_recursive++; // Only pass true for "force" when the value changed or not used // recursively, to avoid endless recurrence. - apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, buf->b_fname, - value_changed || syn_recursive == 1, buf); + apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, buf->b_fname, value_changed || syn_recursive == 1, + buf); buf->b_flags |= BF_SYN_SET; syn_recursive--; } @@ -3097,9 +3048,7 @@ 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 @@ -3170,8 +3119,7 @@ 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) - FUNC_ATTR_NONNULL_ALL +int findoption(const char *const arg) FUNC_ATTR_NONNULL_ALL { return findoption_len(arg, strlen(arg)); } @@ -3548,20 +3496,18 @@ static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, Opt bool free_oldval = (opt->flags & P_ALLOCED); bool value_changed = false; - optset_T did_set_cb_args = { - .os_varp = varp, - .os_idx = opt_idx, - .os_flags = opt_flags, - .os_oldval = old_value.data, - .os_newval = new_value.data, - .os_value_checked = false, - .os_value_changed = false, - .os_restore_chartab = false, - .os_errbuf = errbuf, - .os_errbuflen = errbuflen, - .os_buf = curbuf, - .os_win = curwin - }; + optset_T did_set_cb_args = { .os_varp = varp, + .os_idx = opt_idx, + .os_flags = opt_flags, + .os_oldval = old_value.data, + .os_newval = new_value.data, + .os_value_checked = false, + .os_value_changed = false, + .os_restore_chartab = false, + .os_errbuf = errbuf, + .os_errbuflen = errbuflen, + .os_buf = curbuf, + .os_win = curwin }; // Disallow changing immutable options. if (opt->immutable && !optval_equal(old_value, new_value)) { @@ -3615,8 +3561,8 @@ static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, Opt // Check the bound for num options. if (new_value.type == kOptValTypeNumber) { - errmsg = check_num_option_bounds((OptInt *)varp, old_value.data.number, errbuf, errbuflen, - errmsg); + errmsg + = check_num_option_bounds((OptInt *)varp, old_value.data.number, errbuf, errbuflen, errmsg); // Re-assign new_value because the new value was modified by the bound check. new_value = optval_from_varp(opt_idx, varp); } @@ -3704,12 +3650,10 @@ static const char *set_option(const int opt_idx, void *varp, OptVal value, int o vimoption_T *opt = &options[opt_idx]; - static const char *optval_type_names[] = { - [kOptValTypeNil] = "Nil", - [kOptValTypeBoolean] = "Boolean", - [kOptValTypeNumber] = "Number", - [kOptValTypeString] = "String" - }; + 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. @@ -3899,8 +3843,8 @@ int find_key_option_len(const char *arg_arg, size_t len, bool has_lt) } 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); + 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; } @@ -3959,13 +3903,12 @@ static void showoptions(bool all, int opt_flags) if (opt_flags & OPT_ONECOLUMN) { len = Columns; } else if (p->flags & P_BOOL) { - len = 1; // a toggle option fits always + len = 1; // a toggle option fits always } else { option_value2string(p, opt_flags); len = (int)strlen(p->fullname) + vim_strsize(NameBuff) + 1; } - if ((len <= INC - GAP && run == 1) - || (len > INC - GAP && run == 2)) { + if ((len <= INC - GAP && run == 1) || (len > INC - GAP && run == 2)) { items[item_count++] = p; } } @@ -3975,26 +3918,24 @@ static void showoptions(bool all, int opt_flags) // display the items if (run == 1) { - assert(Columns <= INT_MAX - GAP - && Columns + GAP >= INT_MIN + 3 - && (Columns + GAP - 3) / INC >= INT_MIN - && (Columns + GAP - 3) / INC <= INT_MAX); + assert(Columns <= INT_MAX - GAP && Columns + GAP >= INT_MIN + 3 + && (Columns + GAP - 3) / INC >= INT_MIN && (Columns + GAP - 3) / INC <= INT_MAX); int cols = (Columns + GAP - 3) / INC; if (cols == 0) { cols = 1; } rows = (item_count + cols - 1) / cols; - } else { // run == 2 + } else { // run == 2 rows = item_count; } for (int row = 0; row < rows && !got_int; row++) { - msg_putchar('\n'); // go to next line - if (got_int) { // 'q' typed in more + msg_putchar('\n'); // go to next line + if (got_int) { // 'q' typed in more break; } int col = 0; for (int i = row; i < item_count; i += rows) { - msg_col = col; // make columns + msg_col = col; // make columns showoneopt(items[i], opt_flags); col += INC; } @@ -4008,7 +3949,7 @@ static void showoptions(bool all, int opt_flags) static int optval_default(vimoption_T *p, const void *varp) { if (varp == NULL) { - return true; // hidden option is always at default + return true; // hidden option is always at default } if (p->flags & P_NUM) { return *(OptInt *)varp == (OptInt)(intptr_t)p->def_val; @@ -4055,13 +3996,13 @@ static void showoneopt(vimoption_T *p, int opt_flags) int save_silent = silent_mode; silent_mode = false; - info_message = true; // use os_msg(), not os_errmsg() + info_message = true; // use os_msg(), not os_errmsg() void *varp = get_varp_scope(p, 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 ((p->flags & P_BOOL) + && ((int *)varp == &curbuf->b_changed ? !curbufIsChanged() : !*(int *)varp)) { msg_puts("no"); } else if ((p->flags & P_BOOL) && *(int *)varp < 0) { msg_puts("--"); @@ -4111,8 +4052,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) // 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))) { + if (!(p->flags & P_NO_MKRC) && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0))) { // skip global option when only doing locals if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL)) { continue; @@ -4134,8 +4074,7 @@ int makeset(FILE *fd, int opt_flags, int local_only) continue; } - if ((opt_flags & OPT_SKIPRTP) - && (p->var == &p_rtp || p->var == &p_pp)) { + if ((opt_flags & OPT_SKIPRTP) && (p->var == &p_rtp || p->var == &p_pp)) { continue; } @@ -4178,14 +4117,13 @@ int makeset(FILE *fd, int opt_flags, int local_only) if (put_setnum(fd, cmd, p->fullname, (OptInt *)varp) == FAIL) { return FAIL; } - } else { // P_STRING + } else { // P_STRING int do_endif = false; // 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, - *(char **)(varp)) < 0 + if (fprintf(fd, "if &%s != '%s'", p->fullname, *(char **)(varp)) < 0 || put_eol(fd) < 0) { return FAIL; } @@ -4245,8 +4183,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char **valuep, uint64_ // If the option value is longer than MAXPATHL, we need to append // each comma separated part of the option separately, so that it // can be expanded when read back. - if (size >= MAXPATHL && (flags & P_COMMA) != 0 - && vim_strchr(*valuep, ',') != NULL) { + if (size >= MAXPATHL && (flags & P_COMMA) != 0 && vim_strchr(*valuep, ',') != NULL) { part = xmalloc(size); // write line break to clear the option, e.g. ':set rtp=' @@ -4310,11 +4247,10 @@ static int put_setnum(FILE *fd, char *cmd, char *name, OptInt *valuep) static int put_setbool(FILE *fd, char *cmd, char *name, int value) { - if (value < 0) { // global/local option using global value + if (value < 0) { // global/local option using global value return OK; } - if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0 - || put_eol(fd) < 0) { + if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0 || put_eol(fd) < 0) { return FAIL; } return OK; @@ -4387,7 +4323,7 @@ void *get_varp_scope_from(vimoption_T *p, int scope, buf_T *buf, win_T *win) case PV_VE: return &(win->w_p_ve); } - return NULL; // "cannot happen" + return NULL; // "cannot happen" } return get_varp_from(p, buf, win); } @@ -4587,6 +4523,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win) return &(buf->b_p_cfu); case PV_OFU: return &(buf->b_p_ofu); + case PV_URF: + return &(buf->b_p_urf); case PV_EOF: return &(buf->b_p_eof); case PV_EOL: @@ -4667,6 +4605,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win) return &(buf->b_p_sw); case PV_TFU: return &(buf->b_p_tfu); + case PV_UMF: + return &(buf->b_p_umf); case PV_TS: return &(buf->b_p_ts); case PV_TW: @@ -4790,7 +4730,7 @@ void copy_winopt(winopt_T *from, winopt_T *to) // Copy the script context so that we know were the value was last set. memmove(to->wo_script_ctx, from->wo_script_ctx, sizeof(to->wo_script_ctx)); - check_winopt(to); // don't want NULL pointers + check_winopt(to); // don't want NULL pointers } /// Check string options in a window for a NULL value. @@ -4898,7 +4838,7 @@ static void init_buf_opt_idx(void) void buf_copy_options(buf_T *buf, int flags) { int should_copy = true; - char *save_p_isk = NULL; // init for GCC + char *save_p_isk = NULL; // init for GCC int did_isk = false; // Skip this when the option defaults have not been set yet. Happens when @@ -4918,8 +4858,7 @@ void buf_copy_options(buf_T *buf, int flags) /// if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER)) && (buf->b_p_initialized - || (!(flags & BCO_ENTER) - && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) { + || (!(flags & BCO_ENTER) && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) { should_copy = false; } @@ -4930,7 +4869,7 @@ void buf_copy_options(buf_T *buf, int flags) // BCO_NOHELP is given or the options were initialized already // (jumping back to a help file with CTRL-T or CTRL-O) bool dont_do_help = ((flags & BCO_NOHELP) && buf->b_help) || buf->b_p_initialized; - if (dont_do_help) { // don't free b_p_isk + if (dont_do_help) { // don't free b_p_isk save_p_isk = buf->b_p_isk; buf->b_p_isk = NULL; } @@ -4938,7 +4877,7 @@ void buf_copy_options(buf_T *buf, int flags) // reset 'readonly' and copy 'fileformat'. if (!buf->b_p_initialized) { free_buf_options(buf, true); - buf->b_p_ro = false; // don't copy readonly + buf->b_p_ro = false; // don't copy readonly buf->b_p_fenc = xstrdup(p_fenc); switch (*p_ffs) { case 'm': @@ -5007,9 +4946,13 @@ void buf_copy_options(buf_T *buf, int flags) set_buflocal_cfu_callback(buf); buf->b_p_ofu = xstrdup(p_ofu); COPY_OPT_SCTX(buf, BV_OFU); + buf->b_p_urf = xstrdup(p_urf); + COPY_OPT_SCTX(buf, BV_URF); set_buflocal_ofu_callback(buf); buf->b_p_tfu = xstrdup(p_tfu); COPY_OPT_SCTX(buf, BV_TFU); + buf->b_p_umf = xstrdup(p_umf); + COPY_OPT_SCTX(buf, BV_UMF); set_buflocal_tfu_callback(buf); buf->b_p_sts = p_sts; COPY_OPT_SCTX(buf, BV_STS); @@ -5161,7 +5104,7 @@ void buf_copy_options(buf_T *buf, int flags) } } - check_buf_options(buf); // make sure we don't have NULLs + check_buf_options(buf); // make sure we don't have NULLs if (did_isk) { (void)buf_init_chartab(buf, false); } @@ -5247,12 +5190,12 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) if (*arg == '<') { while (*p != '>') { - if (*p++ == NUL) { // expand terminal option name + if (*p++ == NUL) { // expand terminal option name return; } } int key = get_special_key_code(arg + 1); - if (key == 0) { // unknown name + if (key == 0) { // unknown name xp->xp_context = EXPAND_NOTHING; return; } @@ -5267,7 +5210,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) p++; } if (*p == NUL) { - return; // expand option name + return; // expand option name } nextchar = *++p; is_term_option = true; @@ -5307,8 +5250,7 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) p++; nextchar = '='; } - if ((nextchar != '=' && nextchar != ':') - || xp->xp_context == EXPAND_BOOL_SETTINGS) { + if ((nextchar != '=' && nextchar != ':') || xp->xp_context == EXPAND_BOOL_SETTINGS) { xp->xp_context = EXPAND_UNSUCCESSFUL; return; } @@ -5340,8 +5282,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 >= 0 && 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; @@ -5359,13 +5300,8 @@ void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags) // Options that have P_EXPAND are considered to all use file/dir expansion. if (flags & P_EXPAND) { p = options[opt_idx].var; - if (p == (char *)&p_bdir - || p == (char *)&p_dir - || p == (char *)&p_path - || p == (char *)&p_pp - || p == (char *)&p_rtp - || p == (char *)&p_cdpath - || p == (char *)&p_vdir) { + if (p == (char *)&p_bdir || p == (char *)&p_dir || p == (char *)&p_path || p == (char *)&p_pp + || p == (char *)&p_rtp || p == (char *)&p_cdpath || p == (char *)&p_vdir) { xp->xp_context = EXPAND_DIRECTORIES; if (p == (char *)&p_path || p == (char *)&p_cdpath) { xp->xp_backslash = XP_BS_THREE; @@ -5489,10 +5425,9 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, char *fuzzystr, int *numM for (int loop = 0; loop <= 1; loop++) { regmatch->rm_ic = ic; if (xp->xp_context != EXPAND_BOOL_SETTINGS) { - for (int match = 0; match < (int)ARRAY_SIZE(names); - match++) { - if (match_str(names[match], regmatch, *matches, - count, (loop == 0), fuzzy, fuzzystr, fuzmatch)) { + for (int match = 0; match < (int)ARRAY_SIZE(names); match++) { + if (match_str(names[match], regmatch, *matches, count, (loop == 0), fuzzy, fuzzystr, + fuzmatch)) { if (loop == 0) { num_normal++; } else { @@ -5502,18 +5437,15 @@ 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 (size_t opt_idx = 0; (str = options[opt_idx].fullname) != NULL; opt_idx++) { if (options[opt_idx].var == NULL) { continue; } - if (xp->xp_context == EXPAND_BOOL_SETTINGS - && !(options[opt_idx].flags & P_BOOL)) { + if (xp->xp_context == EXPAND_BOOL_SETTINGS && !(options[opt_idx].flags & P_BOOL)) { continue; } - if (match_str(str, regmatch, *matches, count, (loop == 0), - fuzzy, fuzzystr, fuzmatch)) { + if (match_str(str, regmatch, *matches, count, (loop == 0), fuzzy, fuzzystr, fuzmatch)) { if (loop == 0) { num_normal++; } else { @@ -5566,10 +5498,8 @@ static char *escape_option_str_cmdline(char *var) // before a file name character. // 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 - && (options[expand_option_idx].flags & P_EXPAND) - && vim_isfilec((uint8_t)var[2]) + if (var[0] == '\\' && var[1] == '\\' && expand_option_idx >= 0 + && (options[expand_option_idx].flags & P_EXPAND) && vim_isfilec((uint8_t)var[2]) && (var[2] != '\\' || (var == buf && var[4] != '\\'))) { STRMOVE(var, var + 1); } @@ -5609,8 +5539,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 < 0 || 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; @@ -5647,9 +5576,8 @@ int ExpandSettingSubtract(expand_T *xp, regmatch_T *regmatch, int *numMatches, c return ExpandOldSetting(numMatches, matches); } - char *option_val = *(char **)get_option_varp_scope_from(expand_option_idx, - expand_option_flags, - curbuf, curwin); + char *option_val + = *(char **)get_option_varp_scope_from(expand_option_idx, expand_option_flags, curbuf, curwin); uint32_t option_flags = options[expand_option_idx].flags; @@ -5760,10 +5688,7 @@ static void option_value2string(vimoption_T *opp, int scope) } else if (wc != 0) { xstrlcpy(NameBuff, transchar((int)wc), sizeof(NameBuff)); } else { - snprintf(NameBuff, - sizeof(NameBuff), - "%" PRId64, - (int64_t)(*(OptInt *)varp)); + snprintf(NameBuff, sizeof(NameBuff), "%" PRId64, (int64_t)(*(OptInt *)varp)); } } else { // P_STRING varp = *(char **)(varp); @@ -5797,8 +5722,7 @@ bool shortmess(int x) { return (p_shm != NULL && (vim_strchr(p_shm, x) != NULL - || (vim_strchr(p_shm, 'a') != NULL - && vim_strchr(SHM_ALL_ABBREVIATIONS, x) != NULL))); + || (vim_strchr(p_shm, 'a') != NULL && vim_strchr(SHM_ALL_ABBREVIATIONS, x) != NULL))); } /// vimrc_found() - Called when a vimrc or "VIMINIT" has been found. @@ -5922,8 +5846,7 @@ int option_set_callback_func(char *optval, Callback *optcb) } typval_T *tv; - if (*optval == '{' - || (strncmp(optval, "function(", 9) == 0) + if (*optval == '{' || (strncmp(optval, "function(", 9) == 0) || (strncmp(optval, "funcref(", 8) == 0)) { // Lambda expression or a funcref tv = eval_expr(optval, NULL); @@ -6009,8 +5932,7 @@ unsigned get_ve_flags(void) /// /// @param win If not NULL, the window to get the local option from; global /// otherwise. -char *get_showbreak_value(win_T *const win) - FUNC_ATTR_WARN_UNUSED_RESULT +char *get_showbreak_value(win_T *const win) FUNC_ATTR_WARN_UNUSED_RESULT { if (win->w_p_sbr == NULL || *win->w_p_sbr == NUL) { return p_sbr; @@ -6040,16 +5962,14 @@ int get_fileformat(const buf_T *buf) /// argument. /// /// @param eap can be NULL! -int get_fileformat_force(const buf_T *buf, const exarg_T *eap) - FUNC_ATTR_NONNULL_ARG(1) +int get_fileformat_force(const buf_T *buf, const exarg_T *eap) FUNC_ATTR_NONNULL_ARG(1) { int c; if (eap != NULL && eap->force_ff != 0) { c = eap->force_ff; } else { - if ((eap != NULL && eap->force_bin != 0) - ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin) { + if ((eap != NULL && eap->force_bin != 0) ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin) { return EOL_UNIX; } c = (unsigned char)(*buf->b_p_ff); @@ -6152,7 +6072,7 @@ size_t copy_option_part(char **option, char *buf, size_t maxlen, char *sep_chars if (*p != NUL && *p != ',') { // skip non-standard separator p++; } - p = skip_to_option_part(p); // p points to next file name + p = skip_to_option_part(p); // p points to next file name *option = p; return len; @@ -6185,25 +6105,21 @@ int win_signcol_count(win_T *wp) } /// Get window or buffer local options -dict_T *get_winbuf_options(const int bufopt) - FUNC_ATTR_WARN_UNUSED_RESULT +dict_T *get_winbuf_options(const int bufopt) FUNC_ATTR_WARN_UNUSED_RESULT { dict_T *const d = tv_dict_alloc(); for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) { struct vimoption *opt = &options[opt_idx]; - if ((bufopt && (opt->indir & PV_BUF)) - || (!bufopt && (opt->indir & PV_WIN))) { + if ((bufopt && (opt->indir & PV_BUF)) || (!bufopt && (opt->indir & PV_WIN))) { 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); + 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); + 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); } @@ -6235,9 +6151,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, { - return (Dictionary)ARRAY_DICT_INIT; - }); + VALIDATE_S(opt_idx >= 0, "option (not found)", name.data, + { return (Dictionary)ARRAY_DICT_INIT; }); return vimoption2dict(&options[opt_idx], scope, buf, win); } @@ -6311,7 +6226,8 @@ static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, wi type = "boolean"; def = BOOLEAN_OBJ((intptr_t)def_val); } else { - type = ""; def = NIL; + type = ""; + def = NIL; } PUT(dict, "type", CSTR_TO_OBJ(type)); PUT(dict, "default", def); diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index b2e8081a08..1bbff8e522 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -23,7 +23,6 @@ typedef union { String string; } OptValData; -/// Option value typedef struct { OptValType type; OptValData data; diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index b0e9ff9434..af2e31f7c7 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -733,6 +733,8 @@ EXTERN char *p_udir; ///< 'undodir' EXTERN int p_udf; ///< 'undofile' EXTERN OptInt p_ul; ///< 'undolevels' EXTERN OptInt p_ur; ///< 'undoreload' +EXTERN char* p_umf; ///< 'usermarkfunc' +EXTERN char* p_urf; ///< 'userregfunction' EXTERN OptInt p_uc; ///< 'updatecount' EXTERN OptInt p_ut; ///< 'updatetime' EXTERN char *p_shada; ///< 'shada' @@ -874,6 +876,8 @@ enum { BV_TX, BV_UDF, BV_UL, + BV_UMF, + BV_URF, BV_WM, BV_VSTS, BV_VTS, diff --git a/src/nvim/options.lua b/src/nvim/options.lua index daaf73d241..4fdee925ad 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -9217,6 +9217,98 @@ return { varname = 'p_ut', }, { + abbreviation='umf', + full_name='usermarkfunc', + desc= [=[ + This option specifies a function to be used to handle any marks + that Neovim does not natively handle. This option unlocks all + characters to be used as marks by the user. + + The 'usermarkfunc' function is called each time a user mark is read + from or written to. + + The 'usermarkfunc' function must take the following parameters: + + {get_or_set} The action being done on this mark (either 'set' + or 'get' + + {markname} The name of the mark either being read or . + + In case the action is 'get', the 'usermarkfunc' function should return + the content associated with that mark. This can be a number indicating a + line number or it could be a dictionary with the keys: + + {line} the line number + + {col} the column number + + {filename} the filename +< + ]=], + short_desc=N_("Function used to define behavior of user-defined marks."), + type='string', scope={'buffer'}, + varname='p_umf', + defaults={if_true=""} + }, + { + abbreviation='urf', + full_name='userregfunc', + desc= [=[ + This option specifies a function to be used to handle any registers + that Neovim does not natively handle. This option unlocks all + characters to be used as registers by the user. + + The 'userregfunc' function is called each time a user register is read + from or written to. + + The 'userregfunc' function must take the following parameters: + + {action} The action being done on this register (either 'yank' + or 'put' + + {register} The string holding the name of the register. This + is always a single character, though multi-byte + characters are allowed. + + {content} If the action is 'yank' this is the content being + yanked into the register. The content is a dictionary + with the following items: + + {lines} The lines being yanked, as a list. + + {type} The type of yank, either "line", "char", or + "block" + + {width} The width in case of "block" mode. + + {additional_data} Additional data. (can be returned in + put mode). + + In case the action is 'put', the 'userregfunc' function should return + the content to place in that location. The content can either be a + string, in which case "char" mode is inferred, or it can return a + dictionary of the same template that populates 'content'. + + A very simple example of a 'userregfunc' function that behaves exactly + like traditional registers would look like: > + + let s:contents = {} + function! MyUserregFunction(action, register, content) abort + if a:action == "put" + return get(s:contents, a:register, "") + else + let s:contents[a:register] = a:content + endif + endfunction + set userregfunc=MyUserregFunction +< + ]=], + short_desc=N_("Function used to define behavior of user-defined registers."), + type='string', scope={'buffer'}, + varname='p_urf', + defaults={if_true=""} + }, + { abbreviation = 'vsts', cb = 'did_set_varsofttabstop', defaults = { if_true = '' }, 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 <sys/utsname.h> #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/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/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..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" @@ -153,7 +151,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/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 <stddef.h> // 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/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/po/da.po b/src/nvim/po/da.po index 0345d3e243..ba0301589c 100644 --- a/src/nvim/po/da.po +++ b/src/nvim/po/da.po @@ -4049,7 +4049,7 @@ msgid "freeing %ld lines" msgstr "frigør %ld linjer" #, c-format -msgid " into \"%c" +msgid " into \"%s" msgstr " i \"%c" #, c-format diff --git a/src/nvim/po/fr.po b/src/nvim/po/fr.po index d9058326d5..fae6fe2297 100644 --- a/src/nvim/po/fr.po +++ b/src/nvim/po/fr.po @@ -4313,7 +4313,7 @@ msgid "freeing %ld lines" msgstr "libération de %ld lignes" #, c-format -msgid " into \"%c" +msgid " into \"%s" msgstr " dans \"%c" #, c-format diff --git a/src/nvim/po/tr.po b/src/nvim/po/tr.po index f3c55fe9ab..08b97ec180 100644 --- a/src/nvim/po/tr.po +++ b/src/nvim/po/tr.po @@ -4208,7 +4208,7 @@ msgstr[0] "%<PRId64> satır deÄŸiÅŸtirildi" msgstr[1] "%<PRId64> satır deÄŸiÅŸtirildi" #, c-format -msgid " into \"%c" +msgid " into \"%s" msgstr " \"%c" #, c-format diff --git a/src/nvim/po/uk.po b/src/nvim/po/uk.po index 83898cda12..1c1da14a22 100644 --- a/src/nvim/po/uk.po +++ b/src/nvim/po/uk.po @@ -5360,7 +5360,7 @@ msgstr[1] "Змінено %<PRId64> Ñ€Ñдки" msgstr[2] "Змінено %<PRId64> Ñ€Ñдків" #, c-format -msgid " into \"%c" +msgid " into \"%s" msgstr " у \"%c" #, c-format 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/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 <stddef.h> #include <string.h> -#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/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/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/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 <stdbool.h> #include <stdint.h> -#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/shada.c b/src/nvim/shada.c index be898142f0..f64dd0e786 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" @@ -1118,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); } } @@ -1382,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; @@ -2373,7 +2372,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse, static inline void shada_initialize_registers(WriteMergerState *const wms, int max_reg_lines) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE { - const void *reg_iter = NULL; + iter_register_T reg_iter = ITER_REGISTER_NULL; const bool limit_reg_lines = max_reg_lines >= 0; do { yankreg_T reg; @@ -2404,7 +2403,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms, int m } } }; - } while (reg_iter != NULL); + } while (reg_iter != ITER_REGISTER_NULL); } /// Replace numbered mark in WriteMergerState @@ -2500,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; @@ -2894,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, { @@ -2914,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/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/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 <stdbool.h> - #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/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..d6a037ffd6 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -26,10 +26,13 @@ #include "nvim/ui.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "state.c.generated.h" // IWYU pragma: export +# include "state.c.generated.h" #endif +size_t hack_keyfix = 0; + void state_enter(VimState *s) + FUNC_ATTR_NONNULL_ALL { while (true) { int check_result = s->check ? s->check(s) : 1; @@ -81,6 +84,18 @@ getkey: } } + // Hacky "fix" for https://github.com/neovim/neovim/issues/20726 + if (key == 3) { + hack_keyfix ++; + if (hack_keyfix == 100) { + got_int = 0; + hack_keyfix = 0; + goto getkey; + } + } else { + hack_keyfix = 0; + } + if (key == K_EVENT) { // An event handler may use the value of reg_executing. // Clear it if it should be cleared when getting the next character. @@ -168,6 +183,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/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 <stdbool.h> - #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/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/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/tui/input.c b/src/nvim/tui/input.c index bdbb5e4872..b9e2d2c9ee 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" @@ -28,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; @@ -140,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); @@ -148,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); @@ -692,20 +696,44 @@ static void handle_raw_buffer(TermInput *input, bool force) } // Push through libtermkey (translates to "<keycode>" 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 + // 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); + if (!termkey_set_buffer_size(input->tk, MAX(bufsize + delta, bufsize * 2))) { + abort(); + } + } + + 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. + if (!termkey_set_buffer_size(input->tk, INPUT_BUFFER_SIZE)) { + abort(); + } + } } static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 197bbcabb5..c71eb633e9 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" @@ -35,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 <assert.h> #include <limits.h> #include <stdbool.h> -#include <stddef.h> #include <stdint.h> #include <stdlib.h> #include <string.h> @@ -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 <stdbool.h> -#include <stddef.h> -#include <stdint.h> +#include <stdint.h> // 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_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/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 <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#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]; +}; 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/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/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/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/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..e38d6b9e9d 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" @@ -4969,6 +4968,17 @@ void free_wininfo(wininfo_T *wip, buf_T *bp) xfree(wip); } +// Free colorcolumns. Has syntax names. +static void free_wp_cc_cols(colorcol_T* cc) +{ + if (cc) { + for (int i = 0; cc[i].col >= 0; i ++) { + xfree(cc[i].syn_name); + } + } + xfree(cc); +} + /// Remove window 'wp' from the window list and free the structure. /// /// @param tp tab page "win" is in, NULL for current @@ -5062,7 +5072,7 @@ static void win_free(win_T *wp, tabpage_T *tp) qf_free_all(wp); - xfree(wp->w_p_cc_cols); + free_wp_cc_cols(wp->w_p_cc_cols); win_free_grid(wp, false); @@ -7308,10 +7318,21 @@ static bool frame_check_width(const frame_T *topfrp, int width) return true; } -/// Simple int comparison function for use with qsort() -static int int_cmp(const void *a, const void *b) +/// Simple colorcol_T comparison function for use with qsort(). +/// Compares the column numbers +static int colorcol_cmp(const void *a, const void *b) { - return *(const int *)a - *(const int *)b; + colorcol_T *ac = (colorcol_T*) a; + colorcol_T *bc = (colorcol_T*) b; + int ret = ac->col - bc->col; + if (ret == 0) { + // qsort() is not inherently stable, so to make it stable, + // the syn_attr field temporarily contains the original index. + // Comparing these will enforce stability. + return ac->syn_attr - bc->syn_attr; + } else { + return ret; + } } /// Handle setting 'colorcolumn' or 'textwidth' in window "wp". @@ -7324,9 +7345,16 @@ const char *check_colorcolumn(win_T *wp) } unsigned count = 0; - int color_cols[256]; + colorcol_T color_cols[256]; + bool do_skip = false; + for (char *s = wp->w_p_cc; *s != NUL && count < 255;) { int col; + int ch = ' '; + char syn_name[256]; + int flags = 0; + syn_name[0] = 0; + if (*s == '-' || *s == '+') { // -N and +N: add to 'textwidth' col = (*s == '-') ? -1 : 1; @@ -7336,7 +7364,7 @@ const char *check_colorcolumn(win_T *wp) } col = col * getdigits_int(&s, true, 0); if (wp->w_buffer->b_p_tw == 0) { - goto skip; // 'textwidth' not set, skip this item + do_skip = true; // 'textwidth' not set, skip this item } assert((col >= 0 && wp->w_buffer->b_p_tw <= INT_MAX - col @@ -7346,15 +7374,63 @@ const char *check_colorcolumn(win_T *wp) && wp->w_buffer->b_p_tw + col <= INT_MAX)); col += (int)wp->w_buffer->b_p_tw; if (col < 0) { - goto skip; + do_skip = true; } } else if (ascii_isdigit(*s)) { col = getdigits_int(&s, true, 0); } else { return e_invarg; } - color_cols[count++] = col - 1; // 1-based to 0-based -skip: + + // Parse the character. + if (*s == '/') { + s ++; + ch = mb_ptr2char_adv((const char**) &s); + if (!ch) { + return e_invarg; + } + } + + // Parse the highlight group. + if (*s == '/') { + s ++; + size_t i = 0; + while(i < sizeof(syn_name) && *s && *s != '/' && *s != ',') { + syn_name[i ++] = *(s++); + } + syn_name[i] = 0; + } + + // Parse extra flags + if (*s == '/') { + s ++; + while (*s != ',' && *s) { + switch (*(s ++)) { + case 'b': + flags |= kColorcolBehind; + break; + + case 'f': + flags |= kColorcolForeground; + break; + + default: + return e_invarg; + } + } + } + + if (!do_skip) { + color_cols[count] = (colorcol_T) { + .col = col - 1, // 1-based to 0-based + .syn_attr = (int) count, // Temporarily use this for stable sorting. + .ch = ch, + .syn_name = syn_name[0] == 0 ? NULL : xstrdup(syn_name), + .flags = flags, + }; + count ++; + } + if (*s == NUL) { break; } @@ -7366,23 +7442,26 @@ skip: } } - xfree(wp->w_p_cc_cols); + free_wp_cc_cols(wp->w_p_cc_cols); if (count == 0) { wp->w_p_cc_cols = NULL; } else { - wp->w_p_cc_cols = xmalloc(sizeof(int) * (count + 1)); + wp->w_p_cc_cols = xmalloc(sizeof(colorcol_T) * (count + 1)); // sort the columns for faster usage on screen redraw inside // win_line() - qsort(color_cols, count, sizeof(int), int_cmp); + qsort(color_cols, count, sizeof(colorcol_T), colorcol_cmp); int j = 0; for (unsigned i = 0; i < count; i++) { // skip duplicates - if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i]) { - wp->w_p_cc_cols[j++] = color_cols[i]; + if (j == 0 || wp->w_p_cc_cols[j - 1].col != color_cols[i].col) { + wp->w_p_cc_cols[j] = color_cols[i]; + // Clear syn_attr, which was used for stable sorting. + wp->w_p_cc_cols[j ++].syn_attr = 0; } } - wp->w_p_cc_cols[j] = -1; // end marker + memset(&wp->w_p_cc_cols[j], 0, sizeof(wp->w_p_cc_cols[j])); + wp->w_p_cc_cols[j].col = -1; // end marker } return NULL; // no error 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); 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" 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" diff --git a/src/nvim/yankmap.c b/src/nvim/yankmap.c new file mode 100644 index 0000000000..591bcffe33 --- /dev/null +++ b/src/nvim/yankmap.c @@ -0,0 +1,45 @@ +#include "nvim/yankmap.h" + +#include "nvim/memory.h" + +void init_yankmap(yankmap_T* map) +{ + memset(map, 0, sizeof(yankmap_T)); + + map->reg_to_yankreg = (Map(int, ptr_t))MAP_INIT; + map->yankreg_to_reg = (Map(ptr_t, int))MAP_INIT; + // map_init(int, ptr_t, &map->reg_to_yankreg); + // map_init(ptr_t, int, &map->yankreg_to_reg); +} + +yankreg_T* yankmap_get(yankmap_T* yankmap, int reg) +{ + bool is_new = false; + yankreg_T** ret + = (yankreg_T**)map_put_ref(int, ptr_t)(&yankmap->reg_to_yankreg, reg, NULL, &is_new); + + if (ret) { + if (is_new) { + *ret = xcalloc(sizeof(yankreg_T), 1); + } + + /* Add the back-reference */ + int* ref = map_put_ref(ptr_t, int)(&yankmap->yankreg_to_reg, *ret, NULL, NULL); + *ref = reg; + + return *ret; + } + + return NULL; +} + +int yankmap_find(yankmap_T* yankmap, yankreg_T* yankreg) +{ + int* ref = map_ref(ptr_t, int)(&yankmap->yankreg_to_reg, yankreg, NULL); + + if (ref) { + return *ref; + } + + return -1; +} diff --git a/src/nvim/yankmap.h b/src/nvim/yankmap.h new file mode 100644 index 0000000000..4468f3a016 --- /dev/null +++ b/src/nvim/yankmap.h @@ -0,0 +1,25 @@ +#ifndef YANK_TRIE_H_ +#define YANK_TRIE_H_ + +#include <stdbool.h> + +#include "nvim/map_defs.h" +#include "nvim/ops.h" + +typedef struct { + /* Register name to yank register. */ + Map(int, ptr_t) reg_to_yankreg; + + /* Yank register to register name. */ + Map(ptr_t, int) yankreg_to_reg; +} yankmap_T; + +void init_yankmap(yankmap_T* yankmap); + +yankreg_T* yankmap_get(yankmap_T* yankmap, int reg); + +yankreg_T* yankmap_put(yankmap_T* yankmap, int index); + +int yankmap_find(yankmap_T* yankmap, yankreg_T* yankreg); + +#endif |