aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/CMakeLists.txt2
-rw-r--r--src/nvim/api/autocmd.c1
-rw-r--r--src/nvim/api/buffer.c1
-rw-r--r--src/nvim/api/command.c1
-rw-r--r--src/nvim/api/deprecated.c1
-rw-r--r--src/nvim/api/extmark.c1
-rw-r--r--src/nvim/api/options.c1
-rw-r--r--src/nvim/api/private/converter.c1
-rw-r--r--src/nvim/api/private/dispatch.h12
-rw-r--r--src/nvim/api/private/helpers.c1
-rw-r--r--src/nvim/api/tabpage.c5
-rw-r--r--src/nvim/api/ui.c1
-rw-r--r--src/nvim/api/ui.h3
-rw-r--r--src/nvim/api/vim.c1
-rw-r--r--src/nvim/api/vimscript.c1
-rw-r--r--src/nvim/api/win_config.c1
-rw-r--r--src/nvim/api/window.c5
-rw-r--r--src/nvim/arabic.c1
-rw-r--r--src/nvim/arglist.c1
-rw-r--r--src/nvim/ascii_defs.h4
-rw-r--r--src/nvim/autocmd.c1
-rw-r--r--src/nvim/autocmd.h57
-rw-r--r--src/nvim/base64.c5
-rw-r--r--src/nvim/buffer_defs.h32
-rw-r--r--src/nvim/buffer_updates.c3
-rw-r--r--src/nvim/bufwrite.c1
-rw-r--r--src/nvim/change.c1
-rw-r--r--src/nvim/channel.h8
-rw-r--r--src/nvim/cmdexpand.c1
-rw-r--r--src/nvim/cmdhist.c2
-rw-r--r--src/nvim/cmdhist.h11
-rw-r--r--src/nvim/context.c1
-rw-r--r--src/nvim/cursor_shape.c1
-rw-r--r--src/nvim/debugger.c1
-rw-r--r--src/nvim/decoration.h10
-rw-r--r--src/nvim/decoration_defs.h2
-rw-r--r--src/nvim/diff.c1
-rw-r--r--src/nvim/diff.h11
-rw-r--r--src/nvim/digraph.c1
-rw-r--r--src/nvim/drawline.c29
-rw-r--r--src/nvim/drawscreen.c14
-rw-r--r--src/nvim/drawscreen.h3
-rw-r--r--src/nvim/edit.c3
-rw-r--r--src/nvim/eval.c14
-rw-r--r--src/nvim/eval.h7
-rw-r--r--src/nvim/eval/buffer.c1
-rw-r--r--src/nvim/eval/decode.c1
-rw-r--r--src/nvim/eval/encode.c1
-rw-r--r--src/nvim/eval/encode.h4
-rw-r--r--src/nvim/eval/executor.c3
-rw-r--r--src/nvim/eval/funcs.c3
-rw-r--r--src/nvim/eval/typval.h12
-rw-r--r--src/nvim/eval/typval_defs.h15
-rw-r--r--src/nvim/eval/userfunc.c7
-rw-r--r--src/nvim/eval/vars.c16
-rw-r--r--src/nvim/event/libuv_process.c1
-rw-r--r--src/nvim/event/multiqueue.c1
-rw-r--r--src/nvim/event/process.c1
-rw-r--r--src/nvim/event/rstream.c1
-rw-r--r--src/nvim/event/signal.c1
-rw-r--r--src/nvim/event/socket.c1
-rw-r--r--src/nvim/event/stream.c1
-rw-r--r--src/nvim/event/time.c1
-rw-r--r--src/nvim/event/wstream.c1
-rw-r--r--src/nvim/ex_cmds.c2
-rw-r--r--src/nvim/ex_cmds.h33
-rw-r--r--src/nvim/ex_docmd.c13
-rw-r--r--src/nvim/ex_docmd.h2
-rw-r--r--src/nvim/ex_eval.c1
-rw-r--r--src/nvim/ex_eval_defs.h8
-rw-r--r--src/nvim/ex_getln.c1
-rw-r--r--src/nvim/ex_session.c1
-rw-r--r--src/nvim/extmark.c13
-rw-r--r--src/nvim/extmark.h2
-rw-r--r--src/nvim/file_search.h16
-rw-r--r--src/nvim/fileio.c1
-rw-r--r--src/nvim/fileio.h63
-rw-r--r--src/nvim/fold.c1
-rw-r--r--src/nvim/fold.h6
-rw-r--r--src/nvim/func_attr.h27
-rw-r--r--src/nvim/garray.c3
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua4
-rw-r--r--src/nvim/generators/gen_declarations.lua30
-rw-r--r--src/nvim/getchar.c1
-rw-r--r--src/nvim/getchar.h3
-rw-r--r--src/nvim/globals.h97
-rw-r--r--src/nvim/hashtab.c1
-rw-r--r--src/nvim/hashtab_defs.h12
-rw-r--r--src/nvim/help.c1
-rw-r--r--src/nvim/highlight.h98
-rw-r--r--src/nvim/highlight_defs.h232
-rw-r--r--src/nvim/highlight_group.c1
-rw-r--r--src/nvim/indent.c1
-rw-r--r--src/nvim/indent_c.c1
-rw-r--r--src/nvim/insexpand.c37
-rw-r--r--src/nvim/insexpand.h3
-rw-r--r--src/nvim/keycodes.c1
-rw-r--r--src/nvim/lib/queue.h26
-rw-r--r--src/nvim/log.c1
-rw-r--r--src/nvim/log.h6
-rw-r--r--src/nvim/lua/converter.c1
-rw-r--r--src/nvim/lua/spell.c4
-rw-r--r--src/nvim/lua/stdlib.c1
-rw-r--r--src/nvim/main.c5
-rw-r--r--src/nvim/map.c3
-rw-r--r--src/nvim/map_defs.h1
-rw-r--r--src/nvim/mapping.c3
-rw-r--r--src/nvim/mapping_defs.h3
-rw-r--r--src/nvim/mark.c159
-rw-r--r--src/nvim/mark.h11
-rw-r--r--src/nvim/mark_defs.h3
-rw-r--r--src/nvim/match.c1
-rw-r--r--src/nvim/math.c5
-rw-r--r--src/nvim/mbyte_defs.h15
-rw-r--r--src/nvim/memline.c1
-rw-r--r--src/nvim/memory.c1
-rw-r--r--src/nvim/menu.c1
-rw-r--r--src/nvim/message.c1
-rw-r--r--src/nvim/message.h3
-rw-r--r--src/nvim/mouse.c1
-rw-r--r--src/nvim/mouse.h2
-rw-r--r--src/nvim/move.c1
-rw-r--r--src/nvim/move.h4
-rw-r--r--src/nvim/msgpack_rpc/channel.c1
-rw-r--r--src/nvim/msgpack_rpc/helpers.c1
-rw-r--r--src/nvim/msgpack_rpc/server.c1
-rw-r--r--src/nvim/normal.c1
-rw-r--r--src/nvim/normal_defs.h3
-rw-r--r--src/nvim/ops.c412
-rw-r--r--src/nvim/ops.h19
-rw-r--r--src/nvim/option.c474
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/option_vars.h4
-rw-r--r--src/nvim/options.lua92
-rw-r--r--src/nvim/optionstr.c1
-rw-r--r--src/nvim/os/env.c5
-rw-r--r--src/nvim/os/fs.c1
-rw-r--r--src/nvim/os/input.c1
-rw-r--r--src/nvim/os/os_defs.h28
-rw-r--r--src/nvim/os/process.c3
-rw-r--r--src/nvim/os/pty_process_unix.c1
-rw-r--r--src/nvim/os/shell.c1
-rw-r--r--src/nvim/os/signal.c1
-rw-r--r--src/nvim/os/stdpaths.c5
-rw-r--r--src/nvim/os/time.c3
-rw-r--r--src/nvim/os/users.c4
-rw-r--r--src/nvim/path.c4
-rw-r--r--src/nvim/path.h43
-rw-r--r--src/nvim/plines.c1
-rw-r--r--src/nvim/po/da.po2
-rw-r--r--src/nvim/po/fr.po2
-rw-r--r--src/nvim/po/tr.po2
-rw-r--r--src/nvim/po/uk.po2
-rw-r--r--src/nvim/pos_defs.h16
-rw-r--r--src/nvim/profile.c1
-rw-r--r--src/nvim/quickfix.c1
-rw-r--r--src/nvim/rbuffer.c5
-rw-r--r--src/nvim/regexp.c1
-rw-r--r--src/nvim/regexp_defs.h22
-rw-r--r--src/nvim/runtime.c1
-rw-r--r--src/nvim/search.c1
-rw-r--r--src/nvim/search.h94
-rw-r--r--src/nvim/shada.c15
-rw-r--r--src/nvim/sign.c7
-rw-r--r--src/nvim/spell.c1
-rw-r--r--src/nvim/spell.h5
-rw-r--r--src/nvim/spell_defs.h11
-rw-r--r--src/nvim/spellfile.c1
-rw-r--r--src/nvim/spellsuggest.c1
-rw-r--r--src/nvim/state.c18
-rw-r--r--src/nvim/strings.c7
-rw-r--r--src/nvim/strings.h6
-rw-r--r--src/nvim/syntax.c1
-rw-r--r--src/nvim/syntax.h43
-rw-r--r--src/nvim/tag.c1
-rw-r--r--src/nvim/terminal.c1
-rw-r--r--src/nvim/testing.c1
-rw-r--r--src/nvim/textformat.c1
-rw-r--r--src/nvim/textobject.c1
-rw-r--r--src/nvim/textobject.h2
-rw-r--r--src/nvim/tui/input.c44
-rw-r--r--src/nvim/tui/tui.c3
-rw-r--r--src/nvim/tui/tui.h2
-rw-r--r--src/nvim/ui.c10
-rw-r--r--src/nvim/ui.h109
-rw-r--r--src/nvim/ui_client.c1
-rw-r--r--src/nvim/ui_compositor.h3
-rw-r--r--src/nvim/ui_defs.h95
-rw-r--r--src/nvim/undo.c1
-rw-r--r--src/nvim/undo_defs.h3
-rw-r--r--src/nvim/usercmd.c1
-rw-r--r--src/nvim/version.c1
-rw-r--r--src/nvim/vim_defs.h44
-rw-r--r--src/nvim/viml/parser/expressions.c1
-rw-r--r--src/nvim/viml/parser/parser.c1
-rw-r--r--src/nvim/window.c111
-rw-r--r--src/nvim/window.h6
-rw-r--r--src/nvim/winfloat.c1
-rw-r--r--src/nvim/winfloat.h11
-rw-r--r--src/nvim/yankmap.c45
-rw-r--r--src/nvim/yankmap.h25
201 files changed, 1985 insertions, 1233 deletions
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(&regs->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